xref: /openbmc/linux/drivers/media/dvb-frontends/dib0090.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1  // SPDX-License-Identifier: GPL-2.0-or-later
2  /*
3   * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
4   *
5   * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
6   *
7   * This code is more or less generated from another driver, please
8   * excuse some codingstyle oddities.
9   */
10  
11  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12  
13  #include <linux/kernel.h>
14  #include <linux/slab.h>
15  #include <linux/i2c.h>
16  #include <linux/mutex.h>
17  
18  #include <media/dvb_frontend.h>
19  
20  #include "dib0090.h"
21  #include "dibx000_common.h"
22  
23  static int debug;
24  module_param(debug, int, 0644);
25  MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
26  
27  #define dprintk(fmt, arg...) do {					\
28  	if (debug)							\
29  		printk(KERN_DEBUG pr_fmt("%s: " fmt),			\
30  		       __func__, ##arg);				\
31  } while (0)
32  
33  #define CONFIG_SYS_DVBT
34  #define CONFIG_SYS_ISDBT
35  #define CONFIG_BAND_CBAND
36  #define CONFIG_BAND_VHF
37  #define CONFIG_BAND_UHF
38  #define CONFIG_DIB0090_USE_PWM_AGC
39  
40  #define EN_LNA0      0x8000
41  #define EN_LNA1      0x4000
42  #define EN_LNA2      0x2000
43  #define EN_LNA3      0x1000
44  #define EN_MIX0      0x0800
45  #define EN_MIX1      0x0400
46  #define EN_MIX2      0x0200
47  #define EN_MIX3      0x0100
48  #define EN_IQADC     0x0040
49  #define EN_PLL       0x0020
50  #define EN_TX        0x0010
51  #define EN_BB        0x0008
52  #define EN_LO        0x0004
53  #define EN_BIAS      0x0001
54  
55  #define EN_IQANA     0x0002
56  #define EN_DIGCLK    0x0080	/* not in the 0x24 reg, only in 0x1b */
57  #define EN_CRYSTAL   0x0002
58  
59  #define EN_UHF		 0x22E9
60  #define EN_VHF		 0x44E9
61  #define EN_LBD		 0x11E9
62  #define EN_SBD		 0x44E9
63  #define EN_CAB		 0x88E9
64  
65  /* Calibration defines */
66  #define      DC_CAL 0x1
67  #define     WBD_CAL 0x2
68  #define    TEMP_CAL 0x4
69  #define CAPTRIM_CAL 0x8
70  
71  #define KROSUS_PLL_LOCKED   0x800
72  #define KROSUS              0x2
73  
74  /* Use those defines to identify SOC version */
75  #define SOC               0x02
76  #define SOC_7090_P1G_11R1 0x82
77  #define SOC_7090_P1G_21R1 0x8a
78  #define SOC_8090_P1G_11R1 0x86
79  #define SOC_8090_P1G_21R1 0x8e
80  
81  /* else use thos ones to check */
82  #define P1A_B      0x0
83  #define P1C	   0x1
84  #define P1D_E_F    0x3
85  #define P1G	   0x7
86  #define P1G_21R2   0xf
87  
88  #define MP001 0x1		/* Single 9090/8096 */
89  #define MP005 0x4		/* Single Sband */
90  #define MP008 0x6		/* Dual diversity VHF-UHF-LBAND */
91  #define MP009 0x7		/* Dual diversity 29098 CBAND-UHF-LBAND-SBAND */
92  
93  #define pgm_read_word(w) (*w)
94  
95  struct dc_calibration;
96  
97  struct dib0090_tuning {
98  	u32 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
99  	u8 switch_trim;
100  	u8 lna_tune;
101  	u16 lna_bias;
102  	u16 v2i;
103  	u16 mix;
104  	u16 load;
105  	u16 tuner_enable;
106  };
107  
108  struct dib0090_pll {
109  	u32 max_freq;		/* for every frequency less than or equal to that field: this information is correct */
110  	u8 vco_band;
111  	u8 hfdiv_code;
112  	u8 hfdiv;
113  	u8 topresc;
114  };
115  
116  struct dib0090_identity {
117  	u8 version;
118  	u8 product;
119  	u8 p1g;
120  	u8 in_soc;
121  };
122  
123  struct dib0090_state {
124  	struct i2c_adapter *i2c;
125  	struct dvb_frontend *fe;
126  	const struct dib0090_config *config;
127  
128  	u8 current_band;
129  	enum frontend_tune_state tune_state;
130  	u32 current_rf;
131  
132  	u16 wbd_offset;
133  	s16 wbd_target;		/* in dB */
134  
135  	s16 rf_gain_limit;	/* take-over-point: where to split between bb and rf gain */
136  	s16 current_gain;	/* keeps the currently programmed gain */
137  	u8 agc_step;		/* new binary search */
138  
139  	u16 gain[2];		/* for channel monitoring */
140  
141  	const u16 *rf_ramp;
142  	const u16 *bb_ramp;
143  
144  	/* for the software AGC ramps */
145  	u16 bb_1_def;
146  	u16 rf_lt_def;
147  	u16 gain_reg[4];
148  
149  	/* for the captrim/dc-offset search */
150  	s8 step;
151  	s16 adc_diff;
152  	s16 min_adc_diff;
153  
154  	s8 captrim;
155  	s8 fcaptrim;
156  
157  	const struct dc_calibration *dc;
158  	u16 bb6, bb7;
159  
160  	const struct dib0090_tuning *current_tune_table_index;
161  	const struct dib0090_pll *current_pll_table_index;
162  
163  	u8 tuner_is_tuned;
164  	u8 agc_freeze;
165  
166  	struct dib0090_identity identity;
167  
168  	u32 rf_request;
169  	u8 current_standard;
170  
171  	u8 calibrate;
172  	u32 rest;
173  	u16 bias;
174  	s16 temperature;
175  
176  	u8 wbd_calibration_gain;
177  	const struct dib0090_wbd_slope *current_wbd_table;
178  	u16 wbdmux;
179  
180  	/* for the I2C transfer */
181  	struct i2c_msg msg[2];
182  	u8 i2c_write_buffer[3];
183  	u8 i2c_read_buffer[2];
184  	struct mutex i2c_buffer_lock;
185  };
186  
187  struct dib0090_fw_state {
188  	struct i2c_adapter *i2c;
189  	struct dvb_frontend *fe;
190  	struct dib0090_identity identity;
191  	const struct dib0090_config *config;
192  
193  	/* for the I2C transfer */
194  	struct i2c_msg msg;
195  	u8 i2c_write_buffer[2];
196  	u8 i2c_read_buffer[2];
197  	struct mutex i2c_buffer_lock;
198  };
199  
dib0090_read_reg(struct dib0090_state * state,u8 reg)200  static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
201  {
202  	u16 ret;
203  
204  	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
205  		dprintk("could not acquire lock\n");
206  		return 0;
207  	}
208  
209  	state->i2c_write_buffer[0] = reg;
210  
211  	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
212  	state->msg[0].addr = state->config->i2c_address;
213  	state->msg[0].flags = 0;
214  	state->msg[0].buf = state->i2c_write_buffer;
215  	state->msg[0].len = 1;
216  	state->msg[1].addr = state->config->i2c_address;
217  	state->msg[1].flags = I2C_M_RD;
218  	state->msg[1].buf = state->i2c_read_buffer;
219  	state->msg[1].len = 2;
220  
221  	if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
222  		pr_warn("DiB0090 I2C read failed\n");
223  		ret = 0;
224  	} else
225  		ret = (state->i2c_read_buffer[0] << 8)
226  			| state->i2c_read_buffer[1];
227  
228  	mutex_unlock(&state->i2c_buffer_lock);
229  	return ret;
230  }
231  
dib0090_write_reg(struct dib0090_state * state,u32 reg,u16 val)232  static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
233  {
234  	int ret;
235  
236  	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
237  		dprintk("could not acquire lock\n");
238  		return -EINVAL;
239  	}
240  
241  	state->i2c_write_buffer[0] = reg & 0xff;
242  	state->i2c_write_buffer[1] = val >> 8;
243  	state->i2c_write_buffer[2] = val & 0xff;
244  
245  	memset(state->msg, 0, sizeof(struct i2c_msg));
246  	state->msg[0].addr = state->config->i2c_address;
247  	state->msg[0].flags = 0;
248  	state->msg[0].buf = state->i2c_write_buffer;
249  	state->msg[0].len = 3;
250  
251  	if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
252  		pr_warn("DiB0090 I2C write failed\n");
253  		ret = -EREMOTEIO;
254  	} else
255  		ret = 0;
256  
257  	mutex_unlock(&state->i2c_buffer_lock);
258  	return ret;
259  }
260  
dib0090_fw_read_reg(struct dib0090_fw_state * state,u8 reg)261  static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
262  {
263  	u16 ret;
264  
265  	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
266  		dprintk("could not acquire lock\n");
267  		return 0;
268  	}
269  
270  	state->i2c_write_buffer[0] = reg;
271  
272  	memset(&state->msg, 0, sizeof(struct i2c_msg));
273  	state->msg.addr = reg;
274  	state->msg.flags = I2C_M_RD;
275  	state->msg.buf = state->i2c_read_buffer;
276  	state->msg.len = 2;
277  	if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
278  		pr_warn("DiB0090 I2C read failed\n");
279  		ret = 0;
280  	} else
281  		ret = (state->i2c_read_buffer[0] << 8)
282  			| state->i2c_read_buffer[1];
283  
284  	mutex_unlock(&state->i2c_buffer_lock);
285  	return ret;
286  }
287  
dib0090_fw_write_reg(struct dib0090_fw_state * state,u8 reg,u16 val)288  static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
289  {
290  	int ret;
291  
292  	if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
293  		dprintk("could not acquire lock\n");
294  		return -EINVAL;
295  	}
296  
297  	state->i2c_write_buffer[0] = val >> 8;
298  	state->i2c_write_buffer[1] = val & 0xff;
299  
300  	memset(&state->msg, 0, sizeof(struct i2c_msg));
301  	state->msg.addr = reg;
302  	state->msg.flags = 0;
303  	state->msg.buf = state->i2c_write_buffer;
304  	state->msg.len = 2;
305  	if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
306  		pr_warn("DiB0090 I2C write failed\n");
307  		ret = -EREMOTEIO;
308  	} else
309  		ret = 0;
310  
311  	mutex_unlock(&state->i2c_buffer_lock);
312  	return ret;
313  }
314  
315  #define HARD_RESET(state) do {  if (cfg->reset) {  if (cfg->sleep) cfg->sleep(fe, 0); msleep(10);  cfg->reset(fe, 1); msleep(10);  cfg->reset(fe, 0); msleep(10);  }  } while (0)
316  #define ADC_TARGET -220
317  #define GAIN_ALPHA 5
318  #define WBD_ALPHA 6
319  #define LPF	100
dib0090_write_regs(struct dib0090_state * state,u8 r,const u16 * b,u8 c)320  static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
321  {
322  	do {
323  		dib0090_write_reg(state, r++, *b++);
324  	} while (--c);
325  }
326  
dib0090_identify(struct dvb_frontend * fe)327  static int dib0090_identify(struct dvb_frontend *fe)
328  {
329  	struct dib0090_state *state = fe->tuner_priv;
330  	u16 v;
331  	struct dib0090_identity *identity = &state->identity;
332  
333  	v = dib0090_read_reg(state, 0x1a);
334  
335  	identity->p1g = 0;
336  	identity->in_soc = 0;
337  
338  	dprintk("Tuner identification (Version = 0x%04x)\n", v);
339  
340  	/* without PLL lock info */
341  	v &= ~KROSUS_PLL_LOCKED;
342  
343  	identity->version = v & 0xff;
344  	identity->product = (v >> 8) & 0xf;
345  
346  	if (identity->product != KROSUS)
347  		goto identification_error;
348  
349  	if ((identity->version & 0x3) == SOC) {
350  		identity->in_soc = 1;
351  		switch (identity->version) {
352  		case SOC_8090_P1G_11R1:
353  			dprintk("SOC 8090 P1-G11R1 Has been detected\n");
354  			identity->p1g = 1;
355  			break;
356  		case SOC_8090_P1G_21R1:
357  			dprintk("SOC 8090 P1-G21R1 Has been detected\n");
358  			identity->p1g = 1;
359  			break;
360  		case SOC_7090_P1G_11R1:
361  			dprintk("SOC 7090 P1-G11R1 Has been detected\n");
362  			identity->p1g = 1;
363  			break;
364  		case SOC_7090_P1G_21R1:
365  			dprintk("SOC 7090 P1-G21R1 Has been detected\n");
366  			identity->p1g = 1;
367  			break;
368  		default:
369  			goto identification_error;
370  		}
371  	} else {
372  		switch ((identity->version >> 5) & 0x7) {
373  		case MP001:
374  			dprintk("MP001 : 9090/8096\n");
375  			break;
376  		case MP005:
377  			dprintk("MP005 : Single Sband\n");
378  			break;
379  		case MP008:
380  			dprintk("MP008 : diversity VHF-UHF-LBAND\n");
381  			break;
382  		case MP009:
383  			dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n");
384  			break;
385  		default:
386  			goto identification_error;
387  		}
388  
389  		switch (identity->version & 0x1f) {
390  		case P1G_21R2:
391  			dprintk("P1G_21R2 detected\n");
392  			identity->p1g = 1;
393  			break;
394  		case P1G:
395  			dprintk("P1G detected\n");
396  			identity->p1g = 1;
397  			break;
398  		case P1D_E_F:
399  			dprintk("P1D/E/F detected\n");
400  			break;
401  		case P1C:
402  			dprintk("P1C detected\n");
403  			break;
404  		case P1A_B:
405  			dprintk("P1-A/B detected: driver is deactivated - not available\n");
406  			goto identification_error;
407  			break;
408  		default:
409  			goto identification_error;
410  		}
411  	}
412  
413  	return 0;
414  
415  identification_error:
416  	return -EIO;
417  }
418  
dib0090_fw_identify(struct dvb_frontend * fe)419  static int dib0090_fw_identify(struct dvb_frontend *fe)
420  {
421  	struct dib0090_fw_state *state = fe->tuner_priv;
422  	struct dib0090_identity *identity = &state->identity;
423  
424  	u16 v = dib0090_fw_read_reg(state, 0x1a);
425  	identity->p1g = 0;
426  	identity->in_soc = 0;
427  
428  	dprintk("FE: Tuner identification (Version = 0x%04x)\n", v);
429  
430  	/* without PLL lock info */
431  	v &= ~KROSUS_PLL_LOCKED;
432  
433  	identity->version = v & 0xff;
434  	identity->product = (v >> 8) & 0xf;
435  
436  	if (identity->product != KROSUS)
437  		goto identification_error;
438  
439  	if ((identity->version & 0x3) == SOC) {
440  		identity->in_soc = 1;
441  		switch (identity->version) {
442  		case SOC_8090_P1G_11R1:
443  			dprintk("SOC 8090 P1-G11R1 Has been detected\n");
444  			identity->p1g = 1;
445  			break;
446  		case SOC_8090_P1G_21R1:
447  			dprintk("SOC 8090 P1-G21R1 Has been detected\n");
448  			identity->p1g = 1;
449  			break;
450  		case SOC_7090_P1G_11R1:
451  			dprintk("SOC 7090 P1-G11R1 Has been detected\n");
452  			identity->p1g = 1;
453  			break;
454  		case SOC_7090_P1G_21R1:
455  			dprintk("SOC 7090 P1-G21R1 Has been detected\n");
456  			identity->p1g = 1;
457  			break;
458  		default:
459  			goto identification_error;
460  		}
461  	} else {
462  		switch ((identity->version >> 5) & 0x7) {
463  		case MP001:
464  			dprintk("MP001 : 9090/8096\n");
465  			break;
466  		case MP005:
467  			dprintk("MP005 : Single Sband\n");
468  			break;
469  		case MP008:
470  			dprintk("MP008 : diversity VHF-UHF-LBAND\n");
471  			break;
472  		case MP009:
473  			dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n");
474  			break;
475  		default:
476  			goto identification_error;
477  		}
478  
479  		switch (identity->version & 0x1f) {
480  		case P1G_21R2:
481  			dprintk("P1G_21R2 detected\n");
482  			identity->p1g = 1;
483  			break;
484  		case P1G:
485  			dprintk("P1G detected\n");
486  			identity->p1g = 1;
487  			break;
488  		case P1D_E_F:
489  			dprintk("P1D/E/F detected\n");
490  			break;
491  		case P1C:
492  			dprintk("P1C detected\n");
493  			break;
494  		case P1A_B:
495  			dprintk("P1-A/B detected: driver is deactivated - not available\n");
496  			goto identification_error;
497  			break;
498  		default:
499  			goto identification_error;
500  		}
501  	}
502  
503  	return 0;
504  
505  identification_error:
506  	return -EIO;
507  }
508  
dib0090_reset_digital(struct dvb_frontend * fe,const struct dib0090_config * cfg)509  static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
510  {
511  	struct dib0090_state *state = fe->tuner_priv;
512  	u16 PllCfg, i, v;
513  
514  	HARD_RESET(state);
515  	dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
516  	if (cfg->in_soc)
517  		return;
518  
519  	dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);	/* PLL, DIG_CLK and CRYSTAL remain */
520  	/* adcClkOutRatio=8->7, release reset */
521  	dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
522  	if (cfg->clkoutdrive != 0)
523  		dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
524  				| (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
525  	else
526  		dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
527  				| (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
528  
529  	/* Read Pll current config * */
530  	PllCfg = dib0090_read_reg(state, 0x21);
531  
532  	/** Reconfigure PLL if current setting is different from default setting **/
533  	if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
534  			&& !cfg->io.pll_bypass) {
535  
536  		/* Set Bypass mode */
537  		PllCfg |= (1 << 15);
538  		dib0090_write_reg(state, 0x21, PllCfg);
539  
540  		/* Set Reset Pll */
541  		PllCfg &= ~(1 << 13);
542  		dib0090_write_reg(state, 0x21, PllCfg);
543  
544  	/*** Set new Pll configuration in bypass and reset state ***/
545  		PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
546  		dib0090_write_reg(state, 0x21, PllCfg);
547  
548  		/* Remove Reset Pll */
549  		PllCfg |= (1 << 13);
550  		dib0090_write_reg(state, 0x21, PllCfg);
551  
552  	/*** Wait for PLL lock ***/
553  		i = 100;
554  		do {
555  			v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
556  			if (v)
557  				break;
558  		} while (--i);
559  
560  		if (i == 0) {
561  			dprintk("Pll: Unable to lock Pll\n");
562  			return;
563  		}
564  
565  		/* Finally Remove Bypass mode */
566  		PllCfg &= ~(1 << 15);
567  		dib0090_write_reg(state, 0x21, PllCfg);
568  	}
569  
570  	if (cfg->io.pll_bypass) {
571  		PllCfg |= (cfg->io.pll_bypass << 15);
572  		dib0090_write_reg(state, 0x21, PllCfg);
573  	}
574  }
575  
dib0090_fw_reset_digital(struct dvb_frontend * fe,const struct dib0090_config * cfg)576  static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
577  {
578  	struct dib0090_fw_state *state = fe->tuner_priv;
579  	u16 PllCfg;
580  	u16 v;
581  	int i;
582  
583  	dprintk("fw reset digital\n");
584  	HARD_RESET(state);
585  
586  	dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
587  	dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);	/* PLL, DIG_CLK and CRYSTAL remain */
588  
589  	dib0090_fw_write_reg(state, 0x20,
590  			((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
591  
592  	v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
593  	if (cfg->clkoutdrive != 0)
594  		v |= cfg->clkoutdrive << 5;
595  	else
596  		v |= 7 << 5;
597  
598  	v |= 2 << 10;
599  	dib0090_fw_write_reg(state, 0x23, v);
600  
601  	/* Read Pll current config * */
602  	PllCfg = dib0090_fw_read_reg(state, 0x21);
603  
604  	/** Reconfigure PLL if current setting is different from default setting **/
605  	if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
606  
607  		/* Set Bypass mode */
608  		PllCfg |= (1 << 15);
609  		dib0090_fw_write_reg(state, 0x21, PllCfg);
610  
611  		/* Set Reset Pll */
612  		PllCfg &= ~(1 << 13);
613  		dib0090_fw_write_reg(state, 0x21, PllCfg);
614  
615  	/*** Set new Pll configuration in bypass and reset state ***/
616  		PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
617  		dib0090_fw_write_reg(state, 0x21, PllCfg);
618  
619  		/* Remove Reset Pll */
620  		PllCfg |= (1 << 13);
621  		dib0090_fw_write_reg(state, 0x21, PllCfg);
622  
623  	/*** Wait for PLL lock ***/
624  		i = 100;
625  		do {
626  			v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
627  			if (v)
628  				break;
629  		} while (--i);
630  
631  		if (i == 0) {
632  			dprintk("Pll: Unable to lock Pll\n");
633  			return -EIO;
634  		}
635  
636  		/* Finally Remove Bypass mode */
637  		PllCfg &= ~(1 << 15);
638  		dib0090_fw_write_reg(state, 0x21, PllCfg);
639  	}
640  
641  	if (cfg->io.pll_bypass) {
642  		PllCfg |= (cfg->io.pll_bypass << 15);
643  		dib0090_fw_write_reg(state, 0x21, PllCfg);
644  	}
645  
646  	return dib0090_fw_identify(fe);
647  }
648  
dib0090_wakeup(struct dvb_frontend * fe)649  static int dib0090_wakeup(struct dvb_frontend *fe)
650  {
651  	struct dib0090_state *state = fe->tuner_priv;
652  	if (state->config->sleep)
653  		state->config->sleep(fe, 0);
654  
655  	/* enable dataTX in case we have been restarted in the wrong moment */
656  	dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
657  	return 0;
658  }
659  
dib0090_sleep(struct dvb_frontend * fe)660  static int dib0090_sleep(struct dvb_frontend *fe)
661  {
662  	struct dib0090_state *state = fe->tuner_priv;
663  	if (state->config->sleep)
664  		state->config->sleep(fe, 1);
665  	return 0;
666  }
667  
dib0090_dcc_freq(struct dvb_frontend * fe,u8 fast)668  void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
669  {
670  	struct dib0090_state *state = fe->tuner_priv;
671  	if (fast)
672  		dib0090_write_reg(state, 0x04, 0);
673  	else
674  		dib0090_write_reg(state, 0x04, 1);
675  }
676  
677  EXPORT_SYMBOL(dib0090_dcc_freq);
678  
679  static const u16 bb_ramp_pwm_normal_socs[] = {
680  	550, /* max BB gain in 10th of dB */
681  	(1<<9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
682  	440,
683  	(4  << 9) | 0, /* BB_RAMP3 = 26dB */
684  	(0  << 9) | 208, /* BB_RAMP4 */
685  	(4  << 9) | 208, /* BB_RAMP5 = 29dB */
686  	(0  << 9) | 440, /* BB_RAMP6 */
687  };
688  
689  static const u16 rf_ramp_pwm_cband_7090p[] = {
690  	280, /* max RF gain in 10th of dB */
691  	18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
692  	504, /* ramp_max = maximum X used on the ramp */
693  	(29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */
694  	(0  << 10) | 504, /* RF_RAMP6, LNA 1 */
695  	(60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */
696  	(0  << 10) | 364, /* RF_RAMP8, LNA 2 */
697  	(34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */
698  	(0  << 10) | 228, /* GAIN_4_2, LNA 3 */
699  	(37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */
700  	(0  << 10) | 109, /* RF_RAMP4, LNA 4 */
701  };
702  
703  static const u16 rf_ramp_pwm_cband_7090e_sensitivity[] = {
704  	186, /* max RF gain in 10th of dB */
705  	40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
706  	746, /* ramp_max = maximum X used on the ramp */
707  	(10 << 10) | 345, /* RF_RAMP5, LNA 1 = 10dB */
708  	(0  << 10) | 746, /* RF_RAMP6, LNA 1 */
709  	(0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */
710  	(0  << 10) | 0, /* RF_RAMP8, LNA 2 */
711  	(28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */
712  	(0  << 10) | 345, /* GAIN_4_2, LNA 3 */
713  	(20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */
714  	(0  << 10) | 200, /* RF_RAMP4, LNA 4 */
715  };
716  
717  static const u16 rf_ramp_pwm_cband_7090e_aci[] = {
718  	86, /* max RF gain in 10th of dB */
719  	40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
720  	345, /* ramp_max = maximum X used on the ramp */
721  	(0 << 10) | 0, /* RF_RAMP5, LNA 1 = 8dB */ /* 7.47 dB */
722  	(0 << 10) | 0, /* RF_RAMP6, LNA 1 */
723  	(0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */
724  	(0 << 10) | 0, /* RF_RAMP8, LNA 2 */
725  	(28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */
726  	(0  << 10) | 345, /* GAIN_4_2, LNA 3 */
727  	(20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */
728  	(0  << 10) | 200, /* RF_RAMP4, LNA 4 */
729  };
730  
731  static const u16 rf_ramp_pwm_cband_8090[] = {
732  	345, /* max RF gain in 10th of dB */
733  	29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
734  	1000, /* ramp_max = maximum X used on the ramp */
735  	(35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */
736  	(0  << 10) | 1000, /* RF_RAMP4, LNA 1 */
737  	(58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */
738  	(0  << 10) | 772, /* RF_RAMP6, LNA 2 */
739  	(27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */
740  	(0  << 10) | 496, /* RF_RAMP8, LNA 3 */
741  	(40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */
742  	(0  << 10) | 200, /* GAIN_4_2, LNA 4 */
743  };
744  
745  static const u16 rf_ramp_pwm_uhf_7090[] = {
746  	407, /* max RF gain in 10th of dB */
747  	13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
748  	529, /* ramp_max = maximum X used on the ramp */
749  	(23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
750  	(0  << 10) | 176, /* RF_RAMP4, LNA 1 */
751  	(63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */
752  	(0  << 10) | 529, /* RF_RAMP6, LNA 2 */
753  	(48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */
754  	(0  << 10) | 400, /* RF_RAMP8, LNA 3 */
755  	(29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */
756  	(0  << 10) | 316, /* GAIN_4_2, LNA 4 */
757  };
758  
759  static const u16 rf_ramp_pwm_uhf_8090[] = {
760  	388, /* max RF gain in 10th of dB */
761  	26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
762  	1008, /* ramp_max = maximum X used on the ramp */
763  	(11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
764  	(0  << 10) | 369, /* RF_RAMP4, LNA 1 */
765  	(41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */
766  	(0  << 10) | 1008, /* RF_RAMP6, LNA 2 */
767  	(27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */
768  	(0  << 10) | 809, /* RF_RAMP8, LNA 3 */
769  	(14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */
770  	(0  << 10) | 659, /* GAIN_4_2, LNA 4 */
771  };
772  
773  /* GENERAL PWM ramp definition for all other Krosus */
774  static const u16 bb_ramp_pwm_normal[] = {
775  	500, /* max BB gain in 10th of dB */
776  	8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
777  	400,
778  	(2  << 9) | 0, /* BB_RAMP3 = 21dB */
779  	(0  << 9) | 168, /* BB_RAMP4 */
780  	(2  << 9) | 168, /* BB_RAMP5 = 29dB */
781  	(0  << 9) | 400, /* BB_RAMP6 */
782  };
783  
784  #if 0
785  /* Currently unused */
786  static const u16 bb_ramp_pwm_boost[] = {
787  	550, /* max BB gain in 10th of dB */
788  	8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
789  	440,
790  	(2  << 9) | 0, /* BB_RAMP3 = 26dB */
791  	(0  << 9) | 208, /* BB_RAMP4 */
792  	(2  << 9) | 208, /* BB_RAMP5 = 29dB */
793  	(0  << 9) | 440, /* BB_RAMP6 */
794  };
795  #endif
796  
797  static const u16 rf_ramp_pwm_cband[] = {
798  	314, /* max RF gain in 10th of dB */
799  	33, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
800  	1023, /* ramp_max = maximum X used on the ramp */
801  	(8  << 10) | 743, /* RF_RAMP3, LNA 1 = 0dB */
802  	(0  << 10) | 1023, /* RF_RAMP4, LNA 1 */
803  	(15 << 10) | 469, /* RF_RAMP5, LNA 2 = 0dB */
804  	(0  << 10) | 742, /* RF_RAMP6, LNA 2 */
805  	(9  << 10) | 234, /* RF_RAMP7, LNA 3 = 0dB */
806  	(0  << 10) | 468, /* RF_RAMP8, LNA 3 */
807  	(9  << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
808  	(0  << 10) | 233, /* GAIN_4_2, LNA 4 */
809  };
810  
811  static const u16 rf_ramp_pwm_vhf[] = {
812  	398, /* max RF gain in 10th of dB */
813  	24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
814  	954, /* ramp_max = maximum X used on the ramp */
815  	(7  << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */
816  	(0  << 10) | 290, /* RF_RAMP4, LNA 1 */
817  	(16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */
818  	(0  << 10) | 954, /* RF_RAMP6, LNA 2 */
819  	(17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */
820  	(0  << 10) | 699, /* RF_RAMP8, LNA 3 */
821  	(7  << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */
822  	(0  << 10) | 580, /* GAIN_4_2, LNA 4 */
823  };
824  
825  static const u16 rf_ramp_pwm_uhf[] = {
826  	398, /* max RF gain in 10th of dB */
827  	24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
828  	954, /* ramp_max = maximum X used on the ramp */
829  	(7  << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */
830  	(0  << 10) | 290, /* RF_RAMP4, LNA 1 */
831  	(16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */
832  	(0  << 10) | 954, /* RF_RAMP6, LNA 2 */
833  	(17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */
834  	(0  << 10) | 699, /* RF_RAMP8, LNA 3 */
835  	(7  << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */
836  	(0  << 10) | 580, /* GAIN_4_2, LNA 4 */
837  };
838  
839  #if 0
840  /* Currently unused */
841  static const u16 rf_ramp_pwm_sband[] = {
842  	253, /* max RF gain in 10th of dB */
843  	38, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
844  	961,
845  	(4  << 10) | 0, /* RF_RAMP3, LNA 1 = 14.1dB */
846  	(0  << 10) | 508, /* RF_RAMP4, LNA 1 */
847  	(9  << 10) | 508, /* RF_RAMP5, LNA 2 = 11.2dB */
848  	(0  << 10) | 961, /* RF_RAMP6, LNA 2 */
849  	(0  << 10) | 0, /* RF_RAMP7, LNA 3 = 0dB */
850  	(0  << 10) | 0, /* RF_RAMP8, LNA 3 */
851  	(0  << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
852  	(0  << 10) | 0, /* GAIN_4_2, LNA 4 */
853  };
854  #endif
855  
856  struct slope {
857  	s16 range;
858  	s16 slope;
859  };
slopes_to_scale(const struct slope * slopes,u8 num,s16 val)860  static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
861  {
862  	u8 i;
863  	u16 rest;
864  	u16 ret = 0;
865  	for (i = 0; i < num; i++) {
866  		if (val > slopes[i].range)
867  			rest = slopes[i].range;
868  		else
869  			rest = val;
870  		ret += (rest * slopes[i].slope) / slopes[i].range;
871  		val -= rest;
872  	}
873  	return ret;
874  }
875  
876  static const struct slope dib0090_wbd_slopes[3] = {
877  	{66, 120},		/* -64,-52: offset -   65 */
878  	{600, 170},		/* -52,-35: 65     -  665 */
879  	{170, 250},		/* -45,-10: 665    - 835 */
880  };
881  
dib0090_wbd_to_db(struct dib0090_state * state,u16 wbd)882  static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
883  {
884  	wbd &= 0x3ff;
885  	if (wbd < state->wbd_offset)
886  		wbd = 0;
887  	else
888  		wbd -= state->wbd_offset;
889  	/* -64dB is the floor */
890  	return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
891  }
892  
dib0090_wbd_target(struct dib0090_state * state,u32 rf)893  static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
894  {
895  	u16 offset = 250;
896  
897  	/* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
898  
899  	if (state->current_band == BAND_VHF)
900  		offset = 650;
901  #ifndef FIRMWARE_FIREFLY
902  	if (state->current_band == BAND_VHF)
903  		offset = state->config->wbd_vhf_offset;
904  	if (state->current_band == BAND_CBAND)
905  		offset = state->config->wbd_cband_offset;
906  #endif
907  
908  	state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
909  	dprintk("wbd-target: %d dB\n", (u32) state->wbd_target);
910  }
911  
912  static const int gain_reg_addr[4] = {
913  	0x08, 0x0a, 0x0f, 0x01
914  };
915  
dib0090_gain_apply(struct dib0090_state * state,s16 gain_delta,s16 top_delta,u8 force)916  static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
917  {
918  	u16 rf, bb, ref;
919  	u16 i, v, gain_reg[4] = { 0 }, gain;
920  	const u16 *g;
921  
922  	if (top_delta < -511)
923  		top_delta = -511;
924  	if (top_delta > 511)
925  		top_delta = 511;
926  
927  	if (force) {
928  		top_delta *= (1 << WBD_ALPHA);
929  		gain_delta *= (1 << GAIN_ALPHA);
930  	}
931  
932  	if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit))	/* overflow */
933  		state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
934  	else
935  		state->rf_gain_limit += top_delta;
936  
937  	if (state->rf_gain_limit < 0)	/*underflow */
938  		state->rf_gain_limit = 0;
939  
940  	/* use gain as a temporary variable and correct current_gain */
941  	gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
942  	if (gain_delta >= ((s16) gain - state->current_gain))	/* overflow */
943  		state->current_gain = gain;
944  	else
945  		state->current_gain += gain_delta;
946  	/* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
947  	if (state->current_gain < 0)
948  		state->current_gain = 0;
949  
950  	/* now split total gain to rf and bb gain */
951  	gain = state->current_gain >> GAIN_ALPHA;
952  
953  	/* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
954  	if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
955  		rf = state->rf_gain_limit >> WBD_ALPHA;
956  		bb = gain - rf;
957  		if (bb > state->bb_ramp[0])
958  			bb = state->bb_ramp[0];
959  	} else {		/* high signal level -> all gains put on RF */
960  		rf = gain;
961  		bb = 0;
962  	}
963  
964  	state->gain[0] = rf;
965  	state->gain[1] = bb;
966  
967  	/* software ramp */
968  	/* Start with RF gains */
969  	g = state->rf_ramp + 1;	/* point on RF LNA1 max gain */
970  	ref = rf;
971  	for (i = 0; i < 7; i++) {	/* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
972  		if (g[0] == 0 || ref < (g[1] - g[0]))	/* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */
973  			v = 0;	/* force the gain to write for the current amp to be null */
974  		else if (ref >= g[1])	/* Gain to set is higher than the high working point of this amp */
975  			v = g[2];	/* force this amp to be full gain */
976  		else		/* compute the value to set to this amp because we are somewhere in his range */
977  			v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
978  
979  		if (i == 0)	/* LNA 1 reg mapping */
980  			gain_reg[0] = v;
981  		else if (i == 1)	/* LNA 2 reg mapping */
982  			gain_reg[0] |= v << 7;
983  		else if (i == 2)	/* LNA 3 reg mapping */
984  			gain_reg[1] = v;
985  		else if (i == 3)	/* LNA 4 reg mapping */
986  			gain_reg[1] |= v << 7;
987  		else if (i == 4)	/* CBAND LNA reg mapping */
988  			gain_reg[2] = v | state->rf_lt_def;
989  		else if (i == 5)	/* BB gain 1 reg mapping */
990  			gain_reg[3] = v << 3;
991  		else if (i == 6)	/* BB gain 2 reg mapping */
992  			gain_reg[3] |= v << 8;
993  
994  		g += 3;		/* go to next gain bloc */
995  
996  		/* When RF is finished, start with BB */
997  		if (i == 4) {
998  			g = state->bb_ramp + 1;	/* point on BB gain 1 max gain */
999  			ref = bb;
1000  		}
1001  	}
1002  	gain_reg[3] |= state->bb_1_def;
1003  	gain_reg[3] |= ((bb % 10) * 100) / 125;
1004  
1005  #ifdef DEBUG_AGC
1006  	dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x\n", rf, bb, rf + bb,
1007  		gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
1008  #endif
1009  
1010  	/* Write the amplifier regs */
1011  	for (i = 0; i < 4; i++) {
1012  		v = gain_reg[i];
1013  		if (force || state->gain_reg[i] != v) {
1014  			state->gain_reg[i] = v;
1015  			dib0090_write_reg(state, gain_reg_addr[i], v);
1016  		}
1017  	}
1018  }
1019  
dib0090_set_boost(struct dib0090_state * state,int onoff)1020  static void dib0090_set_boost(struct dib0090_state *state, int onoff)
1021  {
1022  	state->bb_1_def &= 0xdfff;
1023  	state->bb_1_def |= onoff << 13;
1024  }
1025  
dib0090_set_rframp(struct dib0090_state * state,const u16 * cfg)1026  static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
1027  {
1028  	state->rf_ramp = cfg;
1029  }
1030  
dib0090_set_rframp_pwm(struct dib0090_state * state,const u16 * cfg)1031  static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
1032  {
1033  	state->rf_ramp = cfg;
1034  
1035  	dib0090_write_reg(state, 0x2a, 0xffff);
1036  
1037  	dprintk("total RF gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
1038  
1039  	dib0090_write_regs(state, 0x2c, cfg + 3, 6);
1040  	dib0090_write_regs(state, 0x3e, cfg + 9, 2);
1041  }
1042  
dib0090_set_bbramp(struct dib0090_state * state,const u16 * cfg)1043  static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
1044  {
1045  	state->bb_ramp = cfg;
1046  	dib0090_set_boost(state, cfg[0] > 500);	/* we want the boost if the gain is higher that 50dB */
1047  }
1048  
dib0090_set_bbramp_pwm(struct dib0090_state * state,const u16 * cfg)1049  static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
1050  {
1051  	state->bb_ramp = cfg;
1052  
1053  	dib0090_set_boost(state, cfg[0] > 500);	/* we want the boost if the gain is higher that 50dB */
1054  
1055  	dib0090_write_reg(state, 0x33, 0xffff);
1056  	dprintk("total BB gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x33));
1057  	dib0090_write_regs(state, 0x35, cfg + 3, 4);
1058  }
1059  
dib0090_pwm_gain_reset(struct dvb_frontend * fe)1060  void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
1061  {
1062  	struct dib0090_state *state = fe->tuner_priv;
1063  	const u16 *bb_ramp = bb_ramp_pwm_normal; /* default baseband config */
1064  	const u16 *rf_ramp = NULL;
1065  	u8 en_pwm_rf_mux = 1;
1066  
1067  	/* reset the AGC */
1068  	if (state->config->use_pwm_agc) {
1069  		if (state->current_band == BAND_CBAND) {
1070  			if (state->identity.in_soc) {
1071  				bb_ramp = bb_ramp_pwm_normal_socs;
1072  				if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1073  					rf_ramp = rf_ramp_pwm_cband_8090;
1074  				else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) {
1075  					if (state->config->is_dib7090e) {
1076  						if (state->rf_ramp == NULL)
1077  							rf_ramp = rf_ramp_pwm_cband_7090e_sensitivity;
1078  						else
1079  							rf_ramp = state->rf_ramp;
1080  					} else
1081  						rf_ramp = rf_ramp_pwm_cband_7090p;
1082  				}
1083  			} else
1084  				rf_ramp = rf_ramp_pwm_cband;
1085  		} else
1086  
1087  			if (state->current_band == BAND_VHF) {
1088  				if (state->identity.in_soc) {
1089  					bb_ramp = bb_ramp_pwm_normal_socs;
1090  					/* rf_ramp = &rf_ramp_pwm_vhf_socs; */ /* TODO */
1091  				} else
1092  					rf_ramp = rf_ramp_pwm_vhf;
1093  			} else if (state->current_band == BAND_UHF) {
1094  				if (state->identity.in_soc) {
1095  					bb_ramp = bb_ramp_pwm_normal_socs;
1096  					if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1097  						rf_ramp = rf_ramp_pwm_uhf_8090;
1098  					else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1099  						rf_ramp = rf_ramp_pwm_uhf_7090;
1100  				} else
1101  					rf_ramp = rf_ramp_pwm_uhf;
1102  			}
1103  		if (rf_ramp)
1104  			dib0090_set_rframp_pwm(state, rf_ramp);
1105  		dib0090_set_bbramp_pwm(state, bb_ramp);
1106  
1107  		/* activate the ramp generator using PWM control */
1108  		if (state->rf_ramp)
1109  			dprintk("ramp RF gain = %d BAND = %s version = %d\n",
1110  				state->rf_ramp[0],
1111  				(state->current_band == BAND_CBAND) ? "CBAND" : "NOT CBAND",
1112  				state->identity.version & 0x1f);
1113  
1114  		if (rf_ramp && ((state->rf_ramp && state->rf_ramp[0] == 0) ||
1115  		    (state->current_band == BAND_CBAND &&
1116  		    (state->identity.version & 0x1f) <= P1D_E_F))) {
1117  			dprintk("DE-Engage mux for direct gain reg control\n");
1118  			en_pwm_rf_mux = 0;
1119  		} else
1120  			dprintk("Engage mux for PWM control\n");
1121  
1122  		dib0090_write_reg(state, 0x32, (en_pwm_rf_mux << 12) | (en_pwm_rf_mux << 11));
1123  
1124  		/* Set fast servo cutoff to start AGC; 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast*/
1125  		if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1126  			dib0090_write_reg(state, 0x04, 3);
1127  		else
1128  			dib0090_write_reg(state, 0x04, 1);
1129  		dib0090_write_reg(state, 0x39, (1 << 10)); /* 0 gain by default */
1130  	}
1131  }
1132  EXPORT_SYMBOL(dib0090_pwm_gain_reset);
1133  
dib0090_set_dc_servo(struct dvb_frontend * fe,u8 DC_servo_cutoff)1134  void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
1135  {
1136  	struct dib0090_state *state = fe->tuner_priv;
1137  	if (DC_servo_cutoff < 4)
1138  		dib0090_write_reg(state, 0x04, DC_servo_cutoff);
1139  }
1140  EXPORT_SYMBOL(dib0090_set_dc_servo);
1141  
dib0090_get_slow_adc_val(struct dib0090_state * state)1142  static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
1143  {
1144  	u16 adc_val = dib0090_read_reg(state, 0x1d);
1145  	if (state->identity.in_soc)
1146  		adc_val >>= 2;
1147  	return adc_val;
1148  }
1149  
dib0090_gain_control(struct dvb_frontend * fe)1150  int dib0090_gain_control(struct dvb_frontend *fe)
1151  {
1152  	struct dib0090_state *state = fe->tuner_priv;
1153  	enum frontend_tune_state *tune_state = &state->tune_state;
1154  	int ret = 10;
1155  
1156  	u16 wbd_val = 0;
1157  	u8 apply_gain_immediatly = 1;
1158  	s16 wbd_error = 0, adc_error = 0;
1159  
1160  	if (*tune_state == CT_AGC_START) {
1161  		state->agc_freeze = 0;
1162  		dib0090_write_reg(state, 0x04, 0x0);
1163  
1164  #ifdef CONFIG_BAND_SBAND
1165  		if (state->current_band == BAND_SBAND) {
1166  			dib0090_set_rframp(state, rf_ramp_sband);
1167  			dib0090_set_bbramp(state, bb_ramp_boost);
1168  		} else
1169  #endif
1170  #ifdef CONFIG_BAND_VHF
1171  		if (state->current_band == BAND_VHF && !state->identity.p1g) {
1172  			dib0090_set_rframp(state, rf_ramp_pwm_vhf);
1173  			dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1174  		} else
1175  #endif
1176  #ifdef CONFIG_BAND_CBAND
1177  		if (state->current_band == BAND_CBAND && !state->identity.p1g) {
1178  			dib0090_set_rframp(state, rf_ramp_pwm_cband);
1179  			dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1180  		} else
1181  #endif
1182  		if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
1183  			dib0090_set_rframp(state, rf_ramp_pwm_cband_7090p);
1184  			dib0090_set_bbramp(state, bb_ramp_pwm_normal_socs);
1185  		} else {
1186  			dib0090_set_rframp(state, rf_ramp_pwm_uhf);
1187  			dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1188  		}
1189  
1190  		dib0090_write_reg(state, 0x32, 0);
1191  		dib0090_write_reg(state, 0x39, 0);
1192  
1193  		dib0090_wbd_target(state, state->current_rf);
1194  
1195  		state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
1196  		state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
1197  
1198  		*tune_state = CT_AGC_STEP_0;
1199  	} else if (!state->agc_freeze) {
1200  		s16 wbd = 0, i, cnt;
1201  
1202  		int adc;
1203  		wbd_val = dib0090_get_slow_adc_val(state);
1204  
1205  		if (*tune_state == CT_AGC_STEP_0)
1206  			cnt = 5;
1207  		else
1208  			cnt = 1;
1209  
1210  		for (i = 0; i < cnt; i++) {
1211  			wbd_val = dib0090_get_slow_adc_val(state);
1212  			wbd += dib0090_wbd_to_db(state, wbd_val);
1213  		}
1214  		wbd /= cnt;
1215  		wbd_error = state->wbd_target - wbd;
1216  
1217  		if (*tune_state == CT_AGC_STEP_0) {
1218  			if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
1219  #ifdef CONFIG_BAND_CBAND
1220  				/* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
1221  				u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
1222  				if (state->current_band == BAND_CBAND && ltg2) {
1223  					ltg2 >>= 1;
1224  					state->rf_lt_def &= ltg2 << 10;	/* reduce in 3 steps from 7 to 0 */
1225  				}
1226  #endif
1227  			} else {
1228  				state->agc_step = 0;
1229  				*tune_state = CT_AGC_STEP_1;
1230  			}
1231  		} else {
1232  			/* calc the adc power */
1233  			adc = state->config->get_adc_power(fe);
1234  			adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21;	/* included in [0:-700] */
1235  
1236  			adc_error = (s16) (((s32) ADC_TARGET) - adc);
1237  #ifdef CONFIG_STANDARD_DAB
1238  			if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
1239  				adc_error -= 10;
1240  #endif
1241  #ifdef CONFIG_STANDARD_DVBT
1242  			if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
1243  					(state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
1244  				adc_error += 60;
1245  #endif
1246  #ifdef CONFIG_SYS_ISDBT
1247  			if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
1248  								0)
1249  							&&
1250  							((state->fe->dtv_property_cache.layer[0].modulation ==
1251  							  QAM_64)
1252  							 || (state->fe->dtv_property_cache.
1253  								 layer[0].modulation == QAM_16)))
1254  						||
1255  						((state->fe->dtv_property_cache.layer[1].segment_count >
1256  						  0)
1257  						 &&
1258  						 ((state->fe->dtv_property_cache.layer[1].modulation ==
1259  						   QAM_64)
1260  						  || (state->fe->dtv_property_cache.
1261  							  layer[1].modulation == QAM_16)))
1262  						||
1263  						((state->fe->dtv_property_cache.layer[2].segment_count >
1264  						  0)
1265  						 &&
1266  						 ((state->fe->dtv_property_cache.layer[2].modulation ==
1267  						   QAM_64)
1268  						  || (state->fe->dtv_property_cache.
1269  							  layer[2].modulation == QAM_16)))
1270  						)
1271  				)
1272  				adc_error += 60;
1273  #endif
1274  
1275  			if (*tune_state == CT_AGC_STEP_1) {	/* quickly go to the correct range of the ADC power */
1276  				if (abs(adc_error) < 50 || state->agc_step++ > 5) {
1277  
1278  #ifdef CONFIG_STANDARD_DAB
1279  					if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
1280  						dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63));	/* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
1281  						dib0090_write_reg(state, 0x04, 0x0);
1282  					} else
1283  #endif
1284  					{
1285  						dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
1286  						dib0090_write_reg(state, 0x04, 0x01);	/*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
1287  					}
1288  
1289  					*tune_state = CT_AGC_STOP;
1290  				}
1291  			} else {
1292  				/* everything higher than or equal to CT_AGC_STOP means tracking */
1293  				ret = 100;	/* 10ms interval */
1294  				apply_gain_immediatly = 0;
1295  			}
1296  		}
1297  #ifdef DEBUG_AGC
1298  		dprintk
1299  			("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
1300  			 (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
1301  			 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
1302  #endif
1303  	}
1304  
1305  	/* apply gain */
1306  	if (!state->agc_freeze)
1307  		dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
1308  	return ret;
1309  }
1310  
1311  EXPORT_SYMBOL(dib0090_gain_control);
1312  
dib0090_get_current_gain(struct dvb_frontend * fe,u16 * rf,u16 * bb,u16 * rf_gain_limit,u16 * rflt)1313  void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
1314  {
1315  	struct dib0090_state *state = fe->tuner_priv;
1316  	if (rf)
1317  		*rf = state->gain[0];
1318  	if (bb)
1319  		*bb = state->gain[1];
1320  	if (rf_gain_limit)
1321  		*rf_gain_limit = state->rf_gain_limit;
1322  	if (rflt)
1323  		*rflt = (state->rf_lt_def >> 10) & 0x7;
1324  }
1325  
1326  EXPORT_SYMBOL(dib0090_get_current_gain);
1327  
dib0090_get_wbd_target(struct dvb_frontend * fe)1328  u16 dib0090_get_wbd_target(struct dvb_frontend *fe)
1329  {
1330  	struct dib0090_state *state = fe->tuner_priv;
1331  	u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
1332  	s32 current_temp = state->temperature;
1333  	s32 wbd_thot, wbd_tcold;
1334  	const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1335  
1336  	while (f_MHz > wbd->max_freq)
1337  		wbd++;
1338  
1339  	dprintk("using wbd-table-entry with max freq %d\n", wbd->max_freq);
1340  
1341  	if (current_temp < 0)
1342  		current_temp = 0;
1343  	if (current_temp > 128)
1344  		current_temp = 128;
1345  
1346  	state->wbdmux &= ~(7 << 13);
1347  	if (wbd->wbd_gain != 0)
1348  		state->wbdmux |= (wbd->wbd_gain << 13);
1349  	else
1350  		state->wbdmux |= (4 << 13);
1351  
1352  	dib0090_write_reg(state, 0x10, state->wbdmux);
1353  
1354  	wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
1355  	wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
1356  
1357  	wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
1358  
1359  	state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
1360  	dprintk("wbd-target: %d dB\n", (u32) state->wbd_target);
1361  	dprintk("wbd offset applied is %d\n", wbd_tcold);
1362  
1363  	return state->wbd_offset + wbd_tcold;
1364  }
1365  EXPORT_SYMBOL(dib0090_get_wbd_target);
1366  
dib0090_get_wbd_offset(struct dvb_frontend * fe)1367  u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
1368  {
1369  	struct dib0090_state *state = fe->tuner_priv;
1370  	return state->wbd_offset;
1371  }
1372  EXPORT_SYMBOL(dib0090_get_wbd_offset);
1373  
dib0090_set_switch(struct dvb_frontend * fe,u8 sw1,u8 sw2,u8 sw3)1374  int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3)
1375  {
1376  	struct dib0090_state *state = fe->tuner_priv;
1377  
1378  	dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8)
1379  			| ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1));
1380  
1381  	return 0;
1382  }
1383  EXPORT_SYMBOL(dib0090_set_switch);
1384  
dib0090_set_vga(struct dvb_frontend * fe,u8 onoff)1385  int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
1386  {
1387  	struct dib0090_state *state = fe->tuner_priv;
1388  
1389  	dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff)
1390  			| ((onoff & 1) << 15));
1391  	return 0;
1392  }
1393  EXPORT_SYMBOL(dib0090_set_vga);
1394  
dib0090_update_rframp_7090(struct dvb_frontend * fe,u8 cfg_sensitivity)1395  int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity)
1396  {
1397  	struct dib0090_state *state = fe->tuner_priv;
1398  
1399  	if ((!state->identity.p1g) || (!state->identity.in_soc)
1400  			|| ((state->identity.version != SOC_7090_P1G_21R1)
1401  				&& (state->identity.version != SOC_7090_P1G_11R1))) {
1402  		dprintk("%s() function can only be used for dib7090P\n", __func__);
1403  		return -ENODEV;
1404  	}
1405  
1406  	if (cfg_sensitivity)
1407  		state->rf_ramp = rf_ramp_pwm_cband_7090e_sensitivity;
1408  	else
1409  		state->rf_ramp = rf_ramp_pwm_cband_7090e_aci;
1410  	dib0090_pwm_gain_reset(fe);
1411  
1412  	return 0;
1413  }
1414  EXPORT_SYMBOL(dib0090_update_rframp_7090);
1415  
1416  static const u16 dib0090_defaults[] = {
1417  
1418  	25, 0x01,
1419  	0x0000,
1420  	0x99a0,
1421  	0x6008,
1422  	0x0000,
1423  	0x8bcb,
1424  	0x0000,
1425  	0x0405,
1426  	0x0000,
1427  	0x0000,
1428  	0x0000,
1429  	0xb802,
1430  	0x0300,
1431  	0x2d12,
1432  	0xbac0,
1433  	0x7c00,
1434  	0xdbb9,
1435  	0x0954,
1436  	0x0743,
1437  	0x8000,
1438  	0x0001,
1439  	0x0040,
1440  	0x0100,
1441  	0x0000,
1442  	0xe910,
1443  	0x149e,
1444  
1445  	1, 0x1c,
1446  	0xff2d,
1447  
1448  	1, 0x39,
1449  	0x0000,
1450  
1451  	2, 0x1e,
1452  	0x07FF,
1453  	0x0007,
1454  
1455  	1, 0x24,
1456  	EN_UHF | EN_CRYSTAL,
1457  
1458  	2, 0x3c,
1459  	0x3ff,
1460  	0x111,
1461  	0
1462  };
1463  
1464  static const u16 dib0090_p1g_additionnal_defaults[] = {
1465  	1, 0x05,
1466  	0xabcd,
1467  
1468  	1, 0x11,
1469  	0x00b4,
1470  
1471  	1, 0x1c,
1472  	0xfffd,
1473  
1474  	1, 0x40,
1475  	0x108,
1476  	0
1477  };
1478  
dib0090_set_default_config(struct dib0090_state * state,const u16 * n)1479  static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
1480  {
1481  	u16 l, r;
1482  
1483  	l = pgm_read_word(n++);
1484  	while (l) {
1485  		r = pgm_read_word(n++);
1486  		do {
1487  			dib0090_write_reg(state, r, pgm_read_word(n++));
1488  			r++;
1489  		} while (--l);
1490  		l = pgm_read_word(n++);
1491  	}
1492  }
1493  
1494  #define CAP_VALUE_MIN (u8)  9
1495  #define CAP_VALUE_MAX (u8) 40
1496  #define HR_MIN	      (u8) 25
1497  #define HR_MAX	      (u8) 40
1498  #define POLY_MIN      (u8)  0
1499  #define POLY_MAX      (u8)  8
1500  
dib0090_set_EFUSE(struct dib0090_state * state)1501  static void dib0090_set_EFUSE(struct dib0090_state *state)
1502  {
1503  	u8 c, h, n;
1504  	u16 e2, e4;
1505  	u16 cal;
1506  
1507  	e2 = dib0090_read_reg(state, 0x26);
1508  	e4 = dib0090_read_reg(state, 0x28);
1509  
1510  	if ((state->identity.version == P1D_E_F) ||
1511  			(state->identity.version == P1G) || (e2 == 0xffff)) {
1512  
1513  		dib0090_write_reg(state, 0x22, 0x10);
1514  		cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
1515  
1516  		if ((cal < 670) || (cal == 1023))
1517  			cal = 850;
1518  		n = 165 - ((cal * 10)>>6) ;
1519  		e2 = e4 = (3<<12) | (34<<6) | (n);
1520  	}
1521  
1522  	if (e2 != e4)
1523  		e2 &= e4; /* Remove the redundancy  */
1524  
1525  	if (e2 != 0xffff) {
1526  		c = e2 & 0x3f;
1527  		n = (e2 >> 12) & 0xf;
1528  		h = (e2 >> 6) & 0x3f;
1529  
1530  		if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
1531  			c = 32;
1532  		else
1533  			c += 14;
1534  		if ((h >= HR_MAX) || (h <= HR_MIN))
1535  			h = 34;
1536  		if ((n >= POLY_MAX) || (n <= POLY_MIN))
1537  			n = 3;
1538  
1539  		dib0090_write_reg(state, 0x13, (h << 10));
1540  		e2 = (n << 11) | ((h >> 2)<<6) | c;
1541  		dib0090_write_reg(state, 0x2, e2); /* Load the BB_2 */
1542  	}
1543  }
1544  
dib0090_reset(struct dvb_frontend * fe)1545  static int dib0090_reset(struct dvb_frontend *fe)
1546  {
1547  	struct dib0090_state *state = fe->tuner_priv;
1548  
1549  	dib0090_reset_digital(fe, state->config);
1550  	if (dib0090_identify(fe) < 0)
1551  		return -EIO;
1552  
1553  #ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
1554  	if (!(state->identity.version & 0x1))	/* it is P1B - reset is already done */
1555  		return 0;
1556  #endif
1557  
1558  	if (!state->identity.in_soc) {
1559  		if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
1560  			dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1561  		else
1562  			dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1563  	}
1564  
1565  	dib0090_set_default_config(state, dib0090_defaults);
1566  
1567  	if (state->identity.in_soc)
1568  		dib0090_write_reg(state, 0x18, 0x2910);  /* charge pump current = 0 */
1569  
1570  	if (state->identity.p1g)
1571  		dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
1572  
1573  	/* Update the efuse : Only available for KROSUS > P1C  and SOC as well*/
1574  	if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
1575  		dib0090_set_EFUSE(state);
1576  
1577  	/* Congigure in function of the crystal */
1578  	if (state->config->force_crystal_mode != 0)
1579  		dib0090_write_reg(state, 0x14,
1580  				state->config->force_crystal_mode & 3);
1581  	else if (state->config->io.clock_khz >= 24000)
1582  		dib0090_write_reg(state, 0x14, 1);
1583  	else
1584  		dib0090_write_reg(state, 0x14, 2);
1585  	dprintk("Pll lock : %d\n", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
1586  
1587  	state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL;	/* enable iq-offset-calibration and wbd-calibration when tuning next time */
1588  
1589  	return 0;
1590  }
1591  
1592  #define steps(u) (((u) > 15) ? ((u)-16) : (u))
1593  #define INTERN_WAIT 10
dib0090_get_offset(struct dib0090_state * state,enum frontend_tune_state * tune_state)1594  static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1595  {
1596  	int ret = INTERN_WAIT * 10;
1597  
1598  	switch (*tune_state) {
1599  	case CT_TUNER_STEP_2:
1600  		/* Turns to positive */
1601  		dib0090_write_reg(state, 0x1f, 0x7);
1602  		*tune_state = CT_TUNER_STEP_3;
1603  		break;
1604  
1605  	case CT_TUNER_STEP_3:
1606  		state->adc_diff = dib0090_read_reg(state, 0x1d);
1607  
1608  		/* Turns to negative */
1609  		dib0090_write_reg(state, 0x1f, 0x4);
1610  		*tune_state = CT_TUNER_STEP_4;
1611  		break;
1612  
1613  	case CT_TUNER_STEP_4:
1614  		state->adc_diff -= dib0090_read_reg(state, 0x1d);
1615  		*tune_state = CT_TUNER_STEP_5;
1616  		ret = 0;
1617  		break;
1618  
1619  	default:
1620  		break;
1621  	}
1622  
1623  	return ret;
1624  }
1625  
1626  struct dc_calibration {
1627  	u8 addr;
1628  	u8 offset;
1629  	u8 pga:1;
1630  	u16 bb1;
1631  	u8 i:1;
1632  };
1633  
1634  static const struct dc_calibration dc_table[] = {
1635  	/* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1636  	{0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
1637  	{0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
1638  	/* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1639  	{0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
1640  	{0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
1641  	{0},
1642  };
1643  
1644  static const struct dc_calibration dc_p1g_table[] = {
1645  	/* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1646  	/* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */
1647  	{0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
1648  	{0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
1649  	/* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1650  	{0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
1651  	{0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
1652  	{0},
1653  };
1654  
dib0090_set_trim(struct dib0090_state * state)1655  static void dib0090_set_trim(struct dib0090_state *state)
1656  {
1657  	u16 *val;
1658  
1659  	if (state->dc->addr == 0x07)
1660  		val = &state->bb7;
1661  	else
1662  		val = &state->bb6;
1663  
1664  	*val &= ~(0x1f << state->dc->offset);
1665  	*val |= state->step << state->dc->offset;
1666  
1667  	dib0090_write_reg(state, state->dc->addr, *val);
1668  }
1669  
dib0090_dc_offset_calibration(struct dib0090_state * state,enum frontend_tune_state * tune_state)1670  static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1671  {
1672  	int ret = 0;
1673  	u16 reg;
1674  
1675  	switch (*tune_state) {
1676  	case CT_TUNER_START:
1677  		dprintk("Start DC offset calibration");
1678  
1679  		/* force vcm2 = 0.8V */
1680  		state->bb6 = 0;
1681  		state->bb7 = 0x040d;
1682  
1683  		/* the LNA AND LO are off */
1684  		reg = dib0090_read_reg(state, 0x24) & 0x0ffb;	/* shutdown lna and lo */
1685  		dib0090_write_reg(state, 0x24, reg);
1686  
1687  		state->wbdmux = dib0090_read_reg(state, 0x10);
1688  		dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
1689  		dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
1690  
1691  		state->dc = dc_table;
1692  
1693  		if (state->identity.p1g)
1694  			state->dc = dc_p1g_table;
1695  
1696  		fallthrough;
1697  	case CT_TUNER_STEP_0:
1698  		dprintk("Start/continue DC calibration for %s path\n",
1699  			(state->dc->i == 1) ? "I" : "Q");
1700  		dib0090_write_reg(state, 0x01, state->dc->bb1);
1701  		dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
1702  
1703  		state->step = 0;
1704  		state->min_adc_diff = 1023;
1705  		*tune_state = CT_TUNER_STEP_1;
1706  		ret = 50;
1707  		break;
1708  
1709  	case CT_TUNER_STEP_1:
1710  		dib0090_set_trim(state);
1711  		*tune_state = CT_TUNER_STEP_2;
1712  		break;
1713  
1714  	case CT_TUNER_STEP_2:
1715  	case CT_TUNER_STEP_3:
1716  	case CT_TUNER_STEP_4:
1717  		ret = dib0090_get_offset(state, tune_state);
1718  		break;
1719  
1720  	case CT_TUNER_STEP_5:	/* found an offset */
1721  		dprintk("adc_diff = %d, current step= %d\n", (u32) state->adc_diff, state->step);
1722  		if (state->step == 0 && state->adc_diff < 0) {
1723  			state->min_adc_diff = -1023;
1724  			dprintk("Change of sign of the minimum adc diff\n");
1725  		}
1726  
1727  		dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d\n", state->adc_diff, state->min_adc_diff, state->step);
1728  
1729  		/* first turn for this frequency */
1730  		if (state->step == 0) {
1731  			if (state->dc->pga && state->adc_diff < 0)
1732  				state->step = 0x10;
1733  			if (state->dc->pga == 0 && state->adc_diff > 0)
1734  				state->step = 0x10;
1735  		}
1736  
1737  		/* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */
1738  		if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
1739  			/* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */
1740  			state->step++;
1741  			state->min_adc_diff = state->adc_diff;
1742  			*tune_state = CT_TUNER_STEP_1;
1743  		} else {
1744  			/* the minimum was what we have seen in the step before */
1745  			if (abs(state->adc_diff) > abs(state->min_adc_diff)) {
1746  				dprintk("Since adc_diff N = %d  > adc_diff step N-1 = %d, Come back one step\n", state->adc_diff, state->min_adc_diff);
1747  				state->step--;
1748  			}
1749  
1750  			dib0090_set_trim(state);
1751  			dprintk("BB Offset Cal, BBreg=%u,Offset=%d,Value Set=%d\n",
1752  				state->dc->addr, state->adc_diff, state->step);
1753  
1754  			state->dc++;
1755  			if (state->dc->addr == 0)	/* done */
1756  				*tune_state = CT_TUNER_STEP_6;
1757  			else
1758  				*tune_state = CT_TUNER_STEP_0;
1759  
1760  		}
1761  		break;
1762  
1763  	case CT_TUNER_STEP_6:
1764  		dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1765  		dib0090_write_reg(state, 0x1f, 0x7);
1766  		*tune_state = CT_TUNER_START;	/* reset done -> real tuning can now begin */
1767  		state->calibrate &= ~DC_CAL;
1768  		break;
1769  
1770  	default:
1771  		break;
1772  	}
1773  	return ret;
1774  }
1775  
dib0090_wbd_calibration(struct dib0090_state * state,enum frontend_tune_state * tune_state)1776  static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1777  {
1778  	u8 wbd_gain;
1779  	const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1780  
1781  	switch (*tune_state) {
1782  	case CT_TUNER_START:
1783  		while (state->current_rf / 1000 > wbd->max_freq)
1784  			wbd++;
1785  		if (wbd->wbd_gain != 0)
1786  			wbd_gain = wbd->wbd_gain;
1787  		else {
1788  			wbd_gain = 4;
1789  #if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1790  			if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1791  				wbd_gain = 2;
1792  #endif
1793  		}
1794  
1795  		if (wbd_gain == state->wbd_calibration_gain) {	/* the WBD calibration has already been done */
1796  			*tune_state = CT_TUNER_START;
1797  			state->calibrate &= ~WBD_CAL;
1798  			return 0;
1799  		}
1800  
1801  		dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1802  
1803  		dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1804  		*tune_state = CT_TUNER_STEP_0;
1805  		state->wbd_calibration_gain = wbd_gain;
1806  		return 90;	/* wait for the WBDMUX to switch and for the ADC to sample */
1807  
1808  	case CT_TUNER_STEP_0:
1809  		state->wbd_offset = dib0090_get_slow_adc_val(state);
1810  		dprintk("WBD calibration offset = %d\n", state->wbd_offset);
1811  		*tune_state = CT_TUNER_START;	/* reset done -> real tuning can now begin */
1812  		state->calibrate &= ~WBD_CAL;
1813  		break;
1814  
1815  	default:
1816  		break;
1817  	}
1818  	return 0;
1819  }
1820  
dib0090_set_bandwidth(struct dib0090_state * state)1821  static void dib0090_set_bandwidth(struct dib0090_state *state)
1822  {
1823  	u16 tmp;
1824  
1825  	if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1826  		tmp = (3 << 14);
1827  	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1828  		tmp = (2 << 14);
1829  	else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1830  		tmp = (1 << 14);
1831  	else
1832  		tmp = (0 << 14);
1833  
1834  	state->bb_1_def &= 0x3fff;
1835  	state->bb_1_def |= tmp;
1836  
1837  	dib0090_write_reg(state, 0x01, state->bb_1_def);	/* be sure that we have the right bb-filter */
1838  
1839  	dib0090_write_reg(state, 0x03, 0x6008);	/* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
1840  	dib0090_write_reg(state, 0x04, 0x1);	/* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
1841  	if (state->identity.in_soc) {
1842  		dib0090_write_reg(state, 0x05, 0x9bcf); /* attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 1 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 15 */
1843  	} else {
1844  		dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f));	/* 22 = cap_value */
1845  		dib0090_write_reg(state, 0x05, 0xabcd);	/* = 0xabcd : attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 2 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 13 */
1846  	}
1847  }
1848  
1849  static const struct dib0090_pll dib0090_pll_table[] = {
1850  #ifdef CONFIG_BAND_CBAND
1851  	{56000, 0, 9, 48, 6},
1852  	{70000, 1, 9, 48, 6},
1853  	{87000, 0, 8, 32, 4},
1854  	{105000, 1, 8, 32, 4},
1855  	{115000, 0, 7, 24, 6},
1856  	{140000, 1, 7, 24, 6},
1857  	{170000, 0, 6, 16, 4},
1858  #endif
1859  #ifdef CONFIG_BAND_VHF
1860  	{200000, 1, 6, 16, 4},
1861  	{230000, 0, 5, 12, 6},
1862  	{280000, 1, 5, 12, 6},
1863  	{340000, 0, 4, 8, 4},
1864  	{380000, 1, 4, 8, 4},
1865  	{450000, 0, 3, 6, 6},
1866  #endif
1867  #ifdef CONFIG_BAND_UHF
1868  	{580000, 1, 3, 6, 6},
1869  	{700000, 0, 2, 4, 4},
1870  	{860000, 1, 2, 4, 4},
1871  #endif
1872  #ifdef CONFIG_BAND_LBAND
1873  	{1800000, 1, 0, 2, 4},
1874  #endif
1875  #ifdef CONFIG_BAND_SBAND
1876  	{2900000, 0, 14, 1, 4},
1877  #endif
1878  };
1879  
1880  static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
1881  
1882  #ifdef CONFIG_BAND_CBAND
1883  	{184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1884  	{227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1885  	{380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1886  #endif
1887  #ifdef CONFIG_BAND_UHF
1888  	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1889  	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1890  	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1891  	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1892  	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1893  	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1894  #endif
1895  #ifdef CONFIG_BAND_LBAND
1896  	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1897  	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1898  	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1899  #endif
1900  #ifdef CONFIG_BAND_SBAND
1901  	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1902  	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1903  #endif
1904  };
1905  
1906  static const struct dib0090_tuning dib0090_tuning_table[] = {
1907  
1908  #ifdef CONFIG_BAND_CBAND
1909  	{170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1910  #endif
1911  #ifdef CONFIG_BAND_VHF
1912  	{184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1913  	{227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1914  	{380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1915  #endif
1916  #ifdef CONFIG_BAND_UHF
1917  	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1918  	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1919  	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1920  	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1921  	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1922  	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1923  #endif
1924  #ifdef CONFIG_BAND_LBAND
1925  	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1926  	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1927  	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1928  #endif
1929  #ifdef CONFIG_BAND_SBAND
1930  	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1931  	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1932  #endif
1933  };
1934  
1935  static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
1936  #ifdef CONFIG_BAND_CBAND
1937  	{170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
1938  #endif
1939  #ifdef CONFIG_BAND_VHF
1940  	{184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1941  	{227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1942  	{380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1943  #endif
1944  #ifdef CONFIG_BAND_UHF
1945  	{510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1946  	{540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1947  	{600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1948  	{630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1949  	{680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1950  	{720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1951  	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1952  #endif
1953  #ifdef CONFIG_BAND_LBAND
1954  	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1955  	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1956  	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1957  #endif
1958  #ifdef CONFIG_BAND_SBAND
1959  	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1960  	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1961  #endif
1962  };
1963  
1964  static const struct dib0090_pll dib0090_p1g_pll_table[] = {
1965  #ifdef CONFIG_BAND_CBAND
1966  	{57000, 0, 11, 48, 6},
1967  	{70000, 1, 11, 48, 6},
1968  	{86000, 0, 10, 32, 4},
1969  	{105000, 1, 10, 32, 4},
1970  	{115000, 0, 9, 24, 6},
1971  	{140000, 1, 9, 24, 6},
1972  	{170000, 0, 8, 16, 4},
1973  #endif
1974  #ifdef CONFIG_BAND_VHF
1975  	{200000, 1, 8, 16, 4},
1976  	{230000, 0, 7, 12, 6},
1977  	{280000, 1, 7, 12, 6},
1978  	{340000, 0, 6, 8, 4},
1979  	{380000, 1, 6, 8, 4},
1980  	{455000, 0, 5, 6, 6},
1981  #endif
1982  #ifdef CONFIG_BAND_UHF
1983  	{580000, 1, 5, 6, 6},
1984  	{680000, 0, 4, 4, 4},
1985  	{860000, 1, 4, 4, 4},
1986  #endif
1987  #ifdef CONFIG_BAND_LBAND
1988  	{1800000, 1, 2, 2, 4},
1989  #endif
1990  #ifdef CONFIG_BAND_SBAND
1991  	{2900000, 0, 1, 1, 6},
1992  #endif
1993  };
1994  
1995  static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
1996  #ifdef CONFIG_BAND_CBAND
1997  	{184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1998  	{227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1999  	{380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2000  #endif
2001  #ifdef CONFIG_BAND_UHF
2002  	{520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2003  	{550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2004  	{650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2005  	{750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2006  	{850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2007  	{900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2008  #endif
2009  #ifdef CONFIG_BAND_LBAND
2010  	{1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2011  	{1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2012  	{1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2013  #endif
2014  #ifdef CONFIG_BAND_SBAND
2015  	{2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
2016  	{2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
2017  #endif
2018  };
2019  
2020  static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
2021  #ifdef CONFIG_BAND_CBAND
2022  	{300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2023  	{380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2024  	{570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2025  	{858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2026  #endif
2027  };
2028  
2029  static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
2030  #ifdef CONFIG_BAND_CBAND
2031  	{ 300000,  0 ,  3,  0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2032  	{ 380000,  0 ,  10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2033  	{ 600000,  0 ,  10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2034  	{ 660000,  0 ,  5,  0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
2035  	{ 720000,  0 ,  5,  0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2036  	{ 860000,  0 ,  4,  0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
2037  #endif
2038  };
2039  
dib0090_update_tuning_table_7090(struct dvb_frontend * fe,u8 cfg_sensitivity)2040  int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
2041  		u8 cfg_sensitivity)
2042  {
2043  	struct dib0090_state *state = fe->tuner_priv;
2044  	const struct dib0090_tuning *tune =
2045  		dib0090_tuning_table_cband_7090e_sensitivity;
2046  	static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
2047  		{ 300000,  0 ,  3,  0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2048  		{ 650000,  0 ,  4,  0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
2049  		{ 860000,  0 ,  5,  0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
2050  	};
2051  
2052  	if ((!state->identity.p1g) || (!state->identity.in_soc)
2053  			|| ((state->identity.version != SOC_7090_P1G_21R1)
2054  				&& (state->identity.version != SOC_7090_P1G_11R1))) {
2055  		dprintk("%s() function can only be used for dib7090\n", __func__);
2056  		return -ENODEV;
2057  	}
2058  
2059  	if (cfg_sensitivity)
2060  		tune = dib0090_tuning_table_cband_7090e_sensitivity;
2061  	else
2062  		tune = dib0090_tuning_table_cband_7090e_aci;
2063  
2064  	while (state->rf_request > tune->max_freq)
2065  		tune++;
2066  
2067  	dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
2068  			| (tune->lna_bias & 0x7fff));
2069  	dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
2070  			| ((tune->lna_tune << 6) & 0x07c0));
2071  	return 0;
2072  }
2073  EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
2074  
dib0090_captrim_search(struct dib0090_state * state,enum frontend_tune_state * tune_state)2075  static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2076  {
2077  	int ret = 0;
2078  	u16 lo4 = 0xe900;
2079  
2080  	s16 adc_target;
2081  	u16 adc;
2082  	s8 step_sign;
2083  	u8 force_soft_search = 0;
2084  
2085  	if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
2086  		force_soft_search = 1;
2087  
2088  	if (*tune_state == CT_TUNER_START) {
2089  		dprintk("Start Captrim search : %s\n",
2090  			(force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
2091  		dib0090_write_reg(state, 0x10, 0x2B1);
2092  		dib0090_write_reg(state, 0x1e, 0x0032);
2093  
2094  		if (!state->tuner_is_tuned) {
2095  			/* prepare a complete captrim */
2096  			if (!state->identity.p1g || force_soft_search)
2097  				state->step = state->captrim = state->fcaptrim = 64;
2098  
2099  			state->current_rf = state->rf_request;
2100  		} else {	/* we are already tuned to this frequency - the configuration is correct  */
2101  			if (!state->identity.p1g || force_soft_search) {
2102  				/* do a minimal captrim even if the frequency has not changed */
2103  				state->step = 4;
2104  				state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
2105  			}
2106  		}
2107  		state->adc_diff = 3000;
2108  		*tune_state = CT_TUNER_STEP_0;
2109  
2110  	} else if (*tune_state == CT_TUNER_STEP_0) {
2111  		if (state->identity.p1g && !force_soft_search) {
2112  			u8 ratio = 31;
2113  
2114  			dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
2115  			dib0090_read_reg(state, 0x40);
2116  			ret = 50;
2117  		} else {
2118  			state->step /= 2;
2119  			dib0090_write_reg(state, 0x18, lo4 | state->captrim);
2120  
2121  			if (state->identity.in_soc)
2122  				ret = 25;
2123  		}
2124  		*tune_state = CT_TUNER_STEP_1;
2125  
2126  	} else if (*tune_state == CT_TUNER_STEP_1) {
2127  		if (state->identity.p1g && !force_soft_search) {
2128  			dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
2129  			dib0090_read_reg(state, 0x40);
2130  
2131  			state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
2132  			dprintk("***Final Captrim= 0x%x\n", state->fcaptrim);
2133  			*tune_state = CT_TUNER_STEP_3;
2134  
2135  		} else {
2136  			/* MERGE for all krosus before P1G */
2137  			adc = dib0090_get_slow_adc_val(state);
2138  			dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV\n", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
2139  
2140  			if (state->rest == 0 || state->identity.in_soc) {	/* Just for 8090P SOCS where auto captrim HW bug : TO CHECK IN ACI for SOCS !!! if 400 for 8090p SOC => tune issue !!! */
2141  				adc_target = 200;
2142  			} else
2143  				adc_target = 400;
2144  
2145  			if (adc >= adc_target) {
2146  				adc -= adc_target;
2147  				step_sign = -1;
2148  			} else {
2149  				adc = adc_target - adc;
2150  				step_sign = 1;
2151  			}
2152  
2153  			if (adc < state->adc_diff) {
2154  				dprintk("CAPTRIM=%d is closer to target (%d/%d)\n", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
2155  				state->adc_diff = adc;
2156  				state->fcaptrim = state->captrim;
2157  			}
2158  
2159  			state->captrim += step_sign * state->step;
2160  			if (state->step >= 1)
2161  				*tune_state = CT_TUNER_STEP_0;
2162  			else
2163  				*tune_state = CT_TUNER_STEP_2;
2164  
2165  			ret = 25;
2166  		}
2167  	} else if (*tune_state == CT_TUNER_STEP_2) {	/* this step is only used by krosus < P1G */
2168  		/*write the final cptrim config */
2169  		dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
2170  
2171  		*tune_state = CT_TUNER_STEP_3;
2172  
2173  	} else if (*tune_state == CT_TUNER_STEP_3) {
2174  		state->calibrate &= ~CAPTRIM_CAL;
2175  		*tune_state = CT_TUNER_STEP_0;
2176  	}
2177  
2178  	return ret;
2179  }
2180  
dib0090_get_temperature(struct dib0090_state * state,enum frontend_tune_state * tune_state)2181  static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2182  {
2183  	int ret = 15;
2184  	s16 val;
2185  
2186  	switch (*tune_state) {
2187  	case CT_TUNER_START:
2188  		state->wbdmux = dib0090_read_reg(state, 0x10);
2189  		dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
2190  
2191  		state->bias = dib0090_read_reg(state, 0x13);
2192  		dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
2193  
2194  		*tune_state = CT_TUNER_STEP_0;
2195  		/* wait for the WBDMUX to switch and for the ADC to sample */
2196  		break;
2197  
2198  	case CT_TUNER_STEP_0:
2199  		state->adc_diff = dib0090_get_slow_adc_val(state);
2200  		dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
2201  		*tune_state = CT_TUNER_STEP_1;
2202  		break;
2203  
2204  	case CT_TUNER_STEP_1:
2205  		val = dib0090_get_slow_adc_val(state);
2206  		state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2207  
2208  		dprintk("temperature: %d C\n", state->temperature - 30);
2209  
2210  		*tune_state = CT_TUNER_STEP_2;
2211  		break;
2212  
2213  	case CT_TUNER_STEP_2:
2214  		dib0090_write_reg(state, 0x13, state->bias);
2215  		dib0090_write_reg(state, 0x10, state->wbdmux);	/* write back original WBDMUX */
2216  
2217  		*tune_state = CT_TUNER_START;
2218  		state->calibrate &= ~TEMP_CAL;
2219  		if (state->config->analog_output == 0)
2220  			dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2221  
2222  		break;
2223  
2224  	default:
2225  		ret = 0;
2226  		break;
2227  	}
2228  	return ret;
2229  }
2230  
2231  #define WBD     0x781		/* 1 1 1 1 0000 0 0 1 */
dib0090_tune(struct dvb_frontend * fe)2232  static int dib0090_tune(struct dvb_frontend *fe)
2233  {
2234  	struct dib0090_state *state = fe->tuner_priv;
2235  	const struct dib0090_tuning *tune = state->current_tune_table_index;
2236  	const struct dib0090_pll *pll = state->current_pll_table_index;
2237  	enum frontend_tune_state *tune_state = &state->tune_state;
2238  
2239  	u16 lo5, lo6, Den, tmp;
2240  	u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
2241  	int ret = 10;		/* 1ms is the default delay most of the time */
2242  	u8 c, i;
2243  
2244  	/************************* VCO ***************************/
2245  	/* Default values for FG                                 */
2246  	/* from these are needed :                               */
2247  	/* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv             */
2248  
2249  	/* in any case we first need to do a calibration if needed */
2250  	if (*tune_state == CT_TUNER_START) {
2251  		/* deactivate DataTX before some calibrations */
2252  		if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2253  			dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2254  		else
2255  			/* Activate DataTX in case a calibration has been done before */
2256  			if (state->config->analog_output == 0)
2257  				dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2258  	}
2259  
2260  	if (state->calibrate & DC_CAL)
2261  		return dib0090_dc_offset_calibration(state, tune_state);
2262  	else if (state->calibrate & WBD_CAL) {
2263  		if (state->current_rf == 0)
2264  			state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2265  		return dib0090_wbd_calibration(state, tune_state);
2266  	} else if (state->calibrate & TEMP_CAL)
2267  		return dib0090_get_temperature(state, tune_state);
2268  	else if (state->calibrate & CAPTRIM_CAL)
2269  		return dib0090_captrim_search(state, tune_state);
2270  
2271  	if (*tune_state == CT_TUNER_START) {
2272  		/* if soc and AGC pwm control, disengage mux to be able to R/W access to 0x01 register to set the right filter (cutoff_freq_select) during the tune sequence, otherwise, SOC SERPAR error when accessing to 0x01 */
2273  		if (state->config->use_pwm_agc && state->identity.in_soc) {
2274  			tmp = dib0090_read_reg(state, 0x39);
2275  			if ((tmp >> 10) & 0x1)
2276  				dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2277  		}
2278  
2279  		state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
2280  		state->rf_request =
2281  			state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
2282  					BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
2283  					freq_offset_khz_vhf);
2284  
2285  		/* in ISDB-T 1seg we shift tuning frequency */
2286  		if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2287  					&& state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2288  			const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2289  			u8 found_offset = 0;
2290  			u32 margin_khz = 100;
2291  
2292  			if (LUT_offset != NULL) {
2293  				while (LUT_offset->RF_freq != 0xffff) {
2294  					if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2295  								&& (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2296  							&& LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2297  						state->rf_request += LUT_offset->offset_khz;
2298  						found_offset = 1;
2299  						break;
2300  					}
2301  					LUT_offset++;
2302  				}
2303  			}
2304  
2305  			if (found_offset == 0)
2306  				state->rf_request += 400;
2307  		}
2308  		if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2309  			state->tuner_is_tuned = 0;
2310  			state->current_rf = 0;
2311  			state->current_standard = 0;
2312  
2313  			tune = dib0090_tuning_table;
2314  			if (state->identity.p1g)
2315  				tune = dib0090_p1g_tuning_table;
2316  
2317  			tmp = (state->identity.version >> 5) & 0x7;
2318  
2319  			if (state->identity.in_soc) {
2320  				if (state->config->force_cband_input) {	/* Use the CBAND input for all band */
2321  					if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2322  							|| state->current_band & BAND_UHF) {
2323  						state->current_band = BAND_CBAND;
2324  						if (state->config->is_dib7090e)
2325  							tune = dib0090_tuning_table_cband_7090e_sensitivity;
2326  						else
2327  							tune = dib0090_tuning_table_cband_7090;
2328  					}
2329  				} else {	/* Use the CBAND input for all band under UHF */
2330  					if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2331  						state->current_band = BAND_CBAND;
2332  						if (state->config->is_dib7090e)
2333  							tune = dib0090_tuning_table_cband_7090e_sensitivity;
2334  						else
2335  							tune = dib0090_tuning_table_cband_7090;
2336  					}
2337  				}
2338  			} else
2339  			 if (tmp == 0x4 || tmp == 0x7) {
2340  				/* CBAND tuner version for VHF */
2341  				if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2342  					state->current_band = BAND_CBAND;	/* Force CBAND */
2343  
2344  					tune = dib0090_tuning_table_fm_vhf_on_cband;
2345  					if (state->identity.p1g)
2346  						tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
2347  				}
2348  			}
2349  
2350  			pll = dib0090_pll_table;
2351  			if (state->identity.p1g)
2352  				pll = dib0090_p1g_pll_table;
2353  
2354  			/* Look for the interval */
2355  			while (state->rf_request > tune->max_freq)
2356  				tune++;
2357  			while (state->rf_request > pll->max_freq)
2358  				pll++;
2359  
2360  			state->current_tune_table_index = tune;
2361  			state->current_pll_table_index = pll;
2362  
2363  			dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
2364  
2365  			VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
2366  
2367  			FREF = state->config->io.clock_khz;
2368  			if (state->config->fref_clock_ratio != 0)
2369  				FREF /= state->config->fref_clock_ratio;
2370  
2371  			FBDiv = (VCOF_kHz / pll->topresc / FREF);
2372  			Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
2373  
2374  			if (Rest < LPF)
2375  				Rest = 0;
2376  			else if (Rest < 2 * LPF)
2377  				Rest = 2 * LPF;
2378  			else if (Rest > (FREF - LPF)) {
2379  				Rest = 0;
2380  				FBDiv += 1;
2381  			} else if (Rest > (FREF - 2 * LPF))
2382  				Rest = FREF - 2 * LPF;
2383  			Rest = (Rest * 6528) / (FREF / 10);
2384  			state->rest = Rest;
2385  
2386  			/* external loop filter, otherwise:
2387  			 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
2388  			 * lo6 = 0x0e34 */
2389  
2390  			if (Rest == 0) {
2391  				if (pll->vco_band)
2392  					lo5 = 0x049f;
2393  				else
2394  					lo5 = 0x041f;
2395  			} else {
2396  				if (pll->vco_band)
2397  					lo5 = 0x049e;
2398  				else if (state->config->analog_output)
2399  					lo5 = 0x041d;
2400  				else
2401  					lo5 = 0x041c;
2402  			}
2403  
2404  			if (state->identity.p1g) {	/* Bias is done automatically in P1G */
2405  				if (state->identity.in_soc) {
2406  					if (state->identity.version == SOC_8090_P1G_11R1)
2407  						lo5 = 0x46f;
2408  					else
2409  						lo5 = 0x42f;
2410  				} else
2411  					lo5 = 0x42c;
2412  			}
2413  
2414  			lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);	/* bit 15 is the split to the slave, we do not do it here */
2415  
2416  			if (!state->config->io.pll_int_loop_filt) {
2417  				if (state->identity.in_soc)
2418  					lo6 = 0xff98;
2419  				else if (state->identity.p1g || (Rest == 0))
2420  					lo6 = 0xfff8;
2421  				else
2422  					lo6 = 0xff28;
2423  			} else
2424  				lo6 = (state->config->io.pll_int_loop_filt << 3);
2425  
2426  			Den = 1;
2427  
2428  			if (Rest > 0) {
2429  				lo6 |= (1 << 2) | 2;
2430  				Den = 255;
2431  			}
2432  			dib0090_write_reg(state, 0x15, (u16) FBDiv);
2433  			if (state->config->fref_clock_ratio != 0)
2434  				dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
2435  			else
2436  				dib0090_write_reg(state, 0x16, (Den << 8) | 1);
2437  			dib0090_write_reg(state, 0x17, (u16) Rest);
2438  			dib0090_write_reg(state, 0x19, lo5);
2439  			dib0090_write_reg(state, 0x1c, lo6);
2440  
2441  			lo6 = tune->tuner_enable;
2442  			if (state->config->analog_output)
2443  				lo6 = (lo6 & 0xff9f) | 0x2;
2444  
2445  			dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
2446  
2447  		}
2448  
2449  		state->current_rf = state->rf_request;
2450  		state->current_standard = state->fe->dtv_property_cache.delivery_system;
2451  
2452  		ret = 20;
2453  		state->calibrate = CAPTRIM_CAL;	/* captrim search now */
2454  	}
2455  
2456  	else if (*tune_state == CT_TUNER_STEP_0) {	/* Warning : because of captrim cal, if you change this step, change it also in _cal.c file because it is the step following captrim cal state machine */
2457  		const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
2458  
2459  		while (state->current_rf / 1000 > wbd->max_freq)
2460  			wbd++;
2461  
2462  		dib0090_write_reg(state, 0x1e, 0x07ff);
2463  		dprintk("Final Captrim: %d\n", (u32) state->fcaptrim);
2464  		dprintk("HFDIV code: %d\n", (u32) pll->hfdiv_code);
2465  		dprintk("VCO = %d\n", (u32) pll->vco_band);
2466  		dprintk("VCOF in kHz: %d ((%d*%d) << 1))\n", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
2467  		dprintk("REFDIV: %d, FREF: %d\n", (u32) 1, (u32) state->config->io.clock_khz);
2468  		dprintk("FBDIV: %d, Rest: %d\n", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2469  		dprintk("Num: %d, Den: %d, SD: %d\n", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2470  			(u32) dib0090_read_reg(state, 0x1c) & 0x3);
2471  
2472  #define WBD     0x781		/* 1 1 1 1 0000 0 0 1 */
2473  		c = 4;
2474  		i = 3;
2475  
2476  		if (wbd->wbd_gain != 0)
2477  			c = wbd->wbd_gain;
2478  
2479  		state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
2480  		dib0090_write_reg(state, 0x10, state->wbdmux);
2481  
2482  		if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
2483  			dprintk("P1G : The cable band is selected and lna_tune = %d\n", tune->lna_tune);
2484  			dib0090_write_reg(state, 0x09, tune->lna_bias);
2485  			dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
2486  		} else
2487  			dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
2488  
2489  		dib0090_write_reg(state, 0x0c, tune->v2i);
2490  		dib0090_write_reg(state, 0x0d, tune->mix);
2491  		dib0090_write_reg(state, 0x0e, tune->load);
2492  		*tune_state = CT_TUNER_STEP_1;
2493  
2494  	} else if (*tune_state == CT_TUNER_STEP_1) {
2495  		/* initialize the lt gain register */
2496  		state->rf_lt_def = 0x7c00;
2497  
2498  		dib0090_set_bandwidth(state);
2499  		state->tuner_is_tuned = 1;
2500  
2501  		state->calibrate |= WBD_CAL;
2502  		state->calibrate |= TEMP_CAL;
2503  		*tune_state = CT_TUNER_STOP;
2504  	} else
2505  		ret = FE_CALLBACK_TIME_NEVER;
2506  	return ret;
2507  }
2508  
dib0090_release(struct dvb_frontend * fe)2509  static void dib0090_release(struct dvb_frontend *fe)
2510  {
2511  	kfree(fe->tuner_priv);
2512  	fe->tuner_priv = NULL;
2513  }
2514  
dib0090_get_tune_state(struct dvb_frontend * fe)2515  enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
2516  {
2517  	struct dib0090_state *state = fe->tuner_priv;
2518  
2519  	return state->tune_state;
2520  }
2521  
2522  EXPORT_SYMBOL(dib0090_get_tune_state);
2523  
dib0090_set_tune_state(struct dvb_frontend * fe,enum frontend_tune_state tune_state)2524  int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2525  {
2526  	struct dib0090_state *state = fe->tuner_priv;
2527  
2528  	state->tune_state = tune_state;
2529  	return 0;
2530  }
2531  
2532  EXPORT_SYMBOL(dib0090_set_tune_state);
2533  
dib0090_get_frequency(struct dvb_frontend * fe,u32 * frequency)2534  static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
2535  {
2536  	struct dib0090_state *state = fe->tuner_priv;
2537  
2538  	*frequency = 1000 * state->current_rf;
2539  	return 0;
2540  }
2541  
dib0090_set_params(struct dvb_frontend * fe)2542  static int dib0090_set_params(struct dvb_frontend *fe)
2543  {
2544  	struct dib0090_state *state = fe->tuner_priv;
2545  	u32 ret;
2546  
2547  	state->tune_state = CT_TUNER_START;
2548  
2549  	do {
2550  		ret = dib0090_tune(fe);
2551  		if (ret == FE_CALLBACK_TIME_NEVER)
2552  			break;
2553  
2554  		/*
2555  		 * Despite dib0090_tune returns time at a 0.1 ms range,
2556  		 * the actual sleep time depends on CONFIG_HZ. The worse case
2557  		 * is when CONFIG_HZ=100. In such case, the minimum granularity
2558  		 * is 10ms. On some real field tests, the tuner sometimes don't
2559  		 * lock when this timer is lower than 10ms. So, enforce a 10ms
2560  		 * granularity and use usleep_range() instead of msleep().
2561  		 */
2562  		ret = 10 * (ret + 99)/100;
2563  		usleep_range(ret * 1000, (ret + 1) * 1000);
2564  	} while (state->tune_state != CT_TUNER_STOP);
2565  
2566  	return 0;
2567  }
2568  
2569  static const struct dvb_tuner_ops dib0090_ops = {
2570  	.info = {
2571  		 .name = "DiBcom DiB0090",
2572  		 .frequency_min_hz  =  45 * MHz,
2573  		 .frequency_max_hz  = 860 * MHz,
2574  		 .frequency_step_hz =   1 * kHz,
2575  		 },
2576  	.release = dib0090_release,
2577  
2578  	.init = dib0090_wakeup,
2579  	.sleep = dib0090_sleep,
2580  	.set_params = dib0090_set_params,
2581  	.get_frequency = dib0090_get_frequency,
2582  };
2583  
2584  static const struct dvb_tuner_ops dib0090_fw_ops = {
2585  	.info = {
2586  		 .name = "DiBcom DiB0090",
2587  		 .frequency_min_hz  =  45 * MHz,
2588  		 .frequency_max_hz  = 860 * MHz,
2589  		 .frequency_step_hz =   1 * kHz,
2590  		 },
2591  	.release = dib0090_release,
2592  
2593  	.init = NULL,
2594  	.sleep = NULL,
2595  	.set_params = NULL,
2596  	.get_frequency = NULL,
2597  };
2598  
2599  static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
2600  	{470, 0, 250, 0, 100, 4},
2601  	{860, 51, 866, 21, 375, 4},
2602  	{1700, 0, 800, 0, 850, 4},
2603  	{2900, 0, 250, 0, 100, 6},
2604  	{0xFFFF, 0, 0, 0, 0, 0},
2605  };
2606  
dib0090_register(struct dvb_frontend * fe,struct i2c_adapter * i2c,const struct dib0090_config * config)2607  struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2608  {
2609  	struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
2610  	if (st == NULL)
2611  		return NULL;
2612  
2613  	st->config = config;
2614  	st->i2c = i2c;
2615  	st->fe = fe;
2616  	mutex_init(&st->i2c_buffer_lock);
2617  	fe->tuner_priv = st;
2618  
2619  	if (config->wbd == NULL)
2620  		st->current_wbd_table = dib0090_wbd_table_default;
2621  	else
2622  		st->current_wbd_table = config->wbd;
2623  
2624  	if (dib0090_reset(fe) != 0)
2625  		goto free_mem;
2626  
2627  	pr_info("DiB0090: successfully identified\n");
2628  	memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
2629  
2630  	return fe;
2631   free_mem:
2632  	kfree(st);
2633  	fe->tuner_priv = NULL;
2634  	return NULL;
2635  }
2636  
2637  EXPORT_SYMBOL_GPL(dib0090_register);
2638  
dib0090_fw_register(struct dvb_frontend * fe,struct i2c_adapter * i2c,const struct dib0090_config * config)2639  struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2640  {
2641  	struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
2642  	if (st == NULL)
2643  		return NULL;
2644  
2645  	st->config = config;
2646  	st->i2c = i2c;
2647  	st->fe = fe;
2648  	mutex_init(&st->i2c_buffer_lock);
2649  	fe->tuner_priv = st;
2650  
2651  	if (dib0090_fw_reset_digital(fe, st->config) != 0)
2652  		goto free_mem;
2653  
2654  	dprintk("DiB0090 FW: successfully identified\n");
2655  	memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
2656  
2657  	return fe;
2658  free_mem:
2659  	kfree(st);
2660  	fe->tuner_priv = NULL;
2661  	return NULL;
2662  }
2663  EXPORT_SYMBOL_GPL(dib0090_fw_register);
2664  
2665  MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2666  MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
2667  MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
2668  MODULE_LICENSE("GPL");
2669