aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/dib3000mc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-09-30 12:39:15 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-30 12:39:15 -0400
commit5ffd1a6aaacc25be8cd0770a51ec6d46add3a276 (patch)
tree5b076c44f8b7ff88dba9a554d7748c6f083c9071 /drivers/media/dvb/frontends/dib3000mc.c
parent0cd43f83d381c4246a08cd775834833d6fd64805 (diff)
parent8dd86eebc5315910ebfd9f30f1674254308be4b3 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (180 commits) V4L/DVB (4641): Trivial: use lowercase letters in hex subsystem ids V4L/DVB (4639): Cx88: add autodetection for alternate revision of Leadtek PVR V4L/DVB (4638): Basic DVB-T and analog TV support for the HVR1300. V4L/DVB (4637): Add a default method for VIDIOC_G_PARM V4L/DVB (4635): Extend bttv and saa7134 to check for both AGP and PCI PCI failure case V4L/DVB (4634): Zr36120: implement pcipci checks V4L/DVB (4632): Zoran: Implement pcipci failure check V4L/DVB (4631): Av7110: remove V4L2_CAP_VBI_CAPTURE flag V4L/DVB (4630): Av7110: FW_LOADER depemdency fixed V4L/DVB (4629): Saa7134: add card support for Proteus Pro 2309 V4L/DVB (4628): Fix VIDIOC_ENUMSTD ioctl in videodev.c V4L/DVB (4627): Vivi crashes with mplayer V4L/DVB (4626): On saa7111/7113, LUMA_CTRL need a different value V4L/DVB (4624): Tvaudio: Replaced kernel_thread() with kthread_run() V4L/DVB (4622): Copy-paste bug in videodev.c V4L/DVB (4620): Fix AGC configuration for MOD3000P-based boards V4L/DVB (4619): Fixes some I2C dependencies on V4L devices V4L/DVB (4617): Problem with dibusb-mb.c USB IDs V4L/DVB (4616): [PATCH] Nebula DigiTV USB RC support V4L/DVB (4614): Export symbol saa7134_tvaudio_setmute from saa7134 for saa7134-alsa ...
Diffstat (limited to 'drivers/media/dvb/frontends/dib3000mc.c')
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c1432
1 files changed, 720 insertions, 712 deletions
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 98673474a140..cc28417fa33a 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -1,913 +1,921 @@
1/* 1/*
2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000P/M-C 2 * Driver for DiBcom DiB3000MC/P-demodulator.
3 * DiBcom (http://www.dibcom.fr/)
4 * 3 *
4 * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) 5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 * 6 *
7 * based on GPL code from DiBCom, which has 7 * This code is partially based on the previous dib3000mc.c .
8 * 8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) 9 * This program is free software; you can redistribute it and/or
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as 10 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2. 11 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */ 12 */
13
23#include <linux/kernel.h> 14#include <linux/kernel.h>
24#include <linux/module.h> 15#include <linux/i2c.h>
25#include <linux/moduleparam.h> 16//#include <linux/init.h>
26#include <linux/init.h> 17//#include <linux/delay.h>
27#include <linux/delay.h> 18//#include <linux/string.h>
28#include <linux/string.h> 19//#include <linux/slab.h>
29#include <linux/slab.h> 20
30 21#include "dvb_frontend.h"
31#include "dib3000-common.h" 22
32#include "dib3000mc_priv.h" 23#include "dib3000mc.h"
33#include "dib3000.h" 24
34
35/* Version information */
36#define DRIVER_VERSION "0.1"
37#define DRIVER_DESC "DiBcom 3000M-C DVB-T demodulator"
38#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
39
40#ifdef CONFIG_DVB_DIBCOM_DEBUG
41static int debug; 25static int debug;
42module_param(debug, int, 0644); 26module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=stat (|-able))."); 27MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
44#endif
45#define deb_info(args...) dprintk(0x01,args)
46#define deb_xfer(args...) dprintk(0x02,args)
47#define deb_setf(args...) dprintk(0x04,args)
48#define deb_getf(args...) dprintk(0x08,args)
49#define deb_stat(args...) dprintk(0x10,args)
50
51static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode,
52 fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth)
53{
54 switch (transmission_mode) {
55 case TRANSMISSION_MODE_2K:
56 wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[0]);
57 break;
58 case TRANSMISSION_MODE_8K:
59 wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[1]);
60 break;
61 default:
62 break;
63 }
64 28
65 switch (bandwidth) { 29#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); } } while (0)
66/* case BANDWIDTH_5_MHZ: 30
67 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[0]); 31struct dib3000mc_state {
68 break; */ 32 struct dvb_frontend demod;
69 case BANDWIDTH_6_MHZ: 33 struct dib3000mc_config *cfg;
70 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[1]); 34
71 break; 35 u8 i2c_addr;
72 case BANDWIDTH_7_MHZ: 36 struct i2c_adapter *i2c_adap;
73 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[2]); 37
74 break; 38 struct dibx000_i2c_master i2c_master;
75 case BANDWIDTH_8_MHZ: 39
76 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[3]); 40 fe_bandwidth_t current_bandwidth;
77 break; 41
78 default: 42 u16 dev_id;
79 break; 43};
44
45static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
46{
47 u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
48 u8 rb[2];
49 struct i2c_msg msg[2] = {
50 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
51 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
52 };
53
54 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
55 dprintk("i2c read error on %d\n",reg);
56
57 return (rb[0] << 8) | rb[1];
58}
59
60static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
61{
62 u8 b[4] = {
63 (reg >> 8) & 0xff, reg & 0xff,
64 (val >> 8) & 0xff, val & 0xff,
65 };
66 struct i2c_msg msg = {
67 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
68 };
69 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
70}
71
72
73static int dib3000mc_identify(struct dib3000mc_state *state)
74{
75 u16 value;
76 if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
77 dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
78 return -EREMOTEIO;
80 } 79 }
81 80
82 switch (mode) { 81 value = dib3000mc_read_word(state, 1026);
83 case 0: /* no impulse */ /* fall through */ 82 if (value != 0x3001 && value != 0x3002) {
84 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[0]); 83 dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
85 break; 84 return -EREMOTEIO;
86 case 1: /* new algo */
87 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]);
88 set_or(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */
89 break;
90 default: /* old algo */
91 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[3]);
92 break;
93 } 85 }
86 state->dev_id = value;
87
88 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
89
94 return 0; 90 return 0;
95} 91}
96 92
97static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset, 93static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
98 fe_transmit_mode_t fft, fe_bandwidth_t bw)
99{ 94{
100 u16 timf_msb,timf_lsb; 95/*
101 s32 tim_offset,tim_sgn; 96 u32 timf_msb, timf_lsb, i;
102 u64 comp1,comp2,comp=0; 97 int tim_sgn ;
103 98 LUInt comp1, comp2, comp ;
104 switch (bw) { 99// u32 tim_offset ;
105 case BANDWIDTH_8_MHZ: comp = DIB3000MC_CLOCK_REF*8; break; 100 comp = 27700 * BW_INDEX_TO_KHZ(bw) / 1000;
106 case BANDWIDTH_7_MHZ: comp = DIB3000MC_CLOCK_REF*7; break; 101 timf_msb = (comp >> 16) & 0x00FF;
107 case BANDWIDTH_6_MHZ: comp = DIB3000MC_CLOCK_REF*6; break; 102 timf_lsb = comp & 0xFFFF;
108 default: err("unknown bandwidth (%d)",bw); break;
109 }
110 timf_msb = (comp >> 16) & 0xff;
111 timf_lsb = (comp & 0xffff);
112 103
113 // Update the timing offset ; 104 // Update the timing offset ;
114 if (upd_offset > 0) { 105 if (update_offset) {
115 if (!state->timing_offset_comp_done) { 106 if (state->timing_offset_comp_done == 0) {
116 msleep(200); 107 usleep(200000);
117 state->timing_offset_comp_done = 1; 108 state->timing_offset_comp_done = 1;
118 } 109 }
119 tim_offset = rd(DIB3000MC_REG_TIMING_OFFS_MSB); 110 tim_offset = dib3000mc_read_word(state, 416);
120 if ((tim_offset & 0x2000) == 0x2000) 111 if ((tim_offset & 0x2000) == 0x2000)
121 tim_offset |= 0xC000; 112 tim_offset |= 0xC000; // PB: This only works if tim_offset is s16 - weird
122 if (fft == TRANSMISSION_MODE_2K) 113
123 tim_offset <<= 2; 114 if (nfft == 0)
115 tim_offset = tim_offset << 2; // PB: Do not store the offset for different things in one variable
124 state->timing_offset += tim_offset; 116 state->timing_offset += tim_offset;
125 } 117 }
126
127 tim_offset = state->timing_offset; 118 tim_offset = state->timing_offset;
119
128 if (tim_offset < 0) { 120 if (tim_offset < 0) {
129 tim_sgn = 1; 121 tim_sgn = 1;
130 tim_offset = -tim_offset; 122 tim_offset = -tim_offset;
131 } else 123 } else
132 tim_sgn = 0; 124 tim_sgn = 0;
133 125
134 comp1 = (u32)tim_offset * (u32)timf_lsb ; 126 comp1 = tim_offset * timf_lsb;
135 comp2 = (u32)tim_offset * (u32)timf_msb ; 127 comp2 = tim_offset * timf_msb;
136 comp = ((comp1 >> 16) + comp2) >> 7; 128 comp = ((comp1 >> 16) + comp2) >> 7;
137 129
138 if (tim_sgn == 0) 130 if (tim_sgn == 0)
139 comp = (u32)(timf_msb << 16) + (u32) timf_lsb + comp; 131 comp = timf_msb * (1<<16) + timf_lsb + comp;
140 else 132 else
141 comp = (u32)(timf_msb << 16) + (u32) timf_lsb - comp ; 133 comp = timf_msb * (1<<16) + timf_lsb - comp;
134
135 timf_msb = (comp>>16)&0xFF ;
136 timf_lsb = comp&0xFFFF;
137*/
138 u32 timf = 1384402 * (BW_INDEX_TO_KHZ(bw) / 1000);
142 139
143 timf_msb = (comp >> 16) & 0xff; 140 dib3000mc_write_word(state, 23, timf >> 16);
144 timf_lsb = comp & 0xffff; 141 dib3000mc_write_word(state, 24, timf & 0xffff);
145 142
146 wr(DIB3000MC_REG_TIMING_FREQ_MSB,timf_msb);
147 wr(DIB3000MC_REG_TIMING_FREQ_LSB,timf_lsb);
148 return 0; 143 return 0;
149} 144}
150 145
151static int dib3000mc_init_auto_scan(struct dib3000_state *state, fe_bandwidth_t bw, int boost) 146static int dib3000mc_setup_pwm3_state(struct dib3000mc_state *state)
152{ 147{
153 if (boost) { 148 if (state->cfg->pwm3_inversion) {
154 wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_ON); 149 dib3000mc_write_word(state, 51, (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
150 dib3000mc_write_word(state, 52, (0 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (2 << 0));
155 } else { 151 } else {
156 wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_OFF); 152 dib3000mc_write_word(state, 51, (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
157 } 153 dib3000mc_write_word(state, 52, (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0));
158 switch (bw) {
159 case BANDWIDTH_8_MHZ:
160 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
161 break;
162 case BANDWIDTH_7_MHZ:
163 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_7mhz);
164 break;
165 case BANDWIDTH_6_MHZ:
166 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_6mhz);
167 break;
168/* case BANDWIDTH_5_MHZ:
169 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz);
170 break;*/
171 case BANDWIDTH_AUTO:
172 return -EOPNOTSUPP;
173 default:
174 err("unknown bandwidth value (%d).",bw);
175 return -EINVAL;
176 }
177 if (boost) {
178 u32 timeout = (rd(DIB3000MC_REG_BW_TIMOUT_MSB) << 16) +
179 rd(DIB3000MC_REG_BW_TIMOUT_LSB);
180 timeout *= 85; timeout >>= 7;
181 wr(DIB3000MC_REG_BW_TIMOUT_MSB,(timeout >> 16) & 0xffff);
182 wr(DIB3000MC_REG_BW_TIMOUT_LSB,timeout & 0xffff);
183 } 154 }
155
156 if (state->cfg->use_pwm3)
157 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
158 else
159 dib3000mc_write_word(state, 245, 0);
160
161 dib3000mc_write_word(state, 1040, 0x3);
184 return 0; 162 return 0;
185} 163}
186 164
187static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con) 165static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
188{ 166{
189 switch (con) { 167 int ret = 0;
190 case QAM_64: 168 u16 fifo_threshold = 1792;
191 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]); 169 u16 outreg = 0;
192 break; 170 u16 outmode = 0;
193 case QAM_16: 171 u16 elecout = 1;
194 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]); 172 u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
195 break; 173
196 case QPSK: 174 dprintk("-I- Setting output mode for demod %p to %d\n",
197 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]); 175 &state->demod, mode);
198 break; 176
199 case QAM_AUTO: 177 switch (mode) {
178 case OUTMODE_HIGH_Z: // disable
179 elecout = 0;
180 break;
181 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
182 outmode = 0;
183 break;
184 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
185 outmode = 1;
186 break;
187 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
188 outmode = 2;
189 break;
190 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
191 elecout = 3;
192 /*ADDR @ 206 :
193 P_smo_error_discard [1;6:6] = 0
194 P_smo_rs_discard [1;5:5] = 0
195 P_smo_pid_parse [1;4:4] = 0
196 P_smo_fifo_flush [1;3:3] = 0
197 P_smo_mode [2;2:1] = 11
198 P_smo_ovf_prot [1;0:0] = 0
199 */
200 smo_reg |= 3 << 1;
201 fifo_threshold = 512;
202 outmode = 5;
203 break;
204 case OUTMODE_DIVERSITY:
205 outmode = 4;
206 elecout = 1;
200 break; 207 break;
201 default: 208 default:
202 warn("unkown constellation."); 209 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
210 outmode = 0;
203 break; 211 break;
204 } 212 }
205 return 0; 213
214 if ((state->cfg->output_mpeg2_in_188_bytes))
215 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
216
217 outreg = dib3000mc_read_word(state, 244) & 0x07FF;
218 outreg |= (outmode << 11);
219 ret |= dib3000mc_write_word(state, 244, outreg);
220 ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
221 ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
222 ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
223 return ret;
206} 224}
207 225
208static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val) 226static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
209{ 227{
210 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; 228 struct dib3000mc_state *state = demod->demodulator_priv;
211 fe_code_rate_t fe_cr = FEC_NONE; 229 u16 bw_cfg[6] = { 0 };
212 u8 fft=0, guard=0, qam=0, alpha=0, sel_hp=0, cr=0, hrch=0; 230 u16 imp_bw_cfg[3] = { 0 };
213 int seq; 231 u16 reg;
214 232
215 switch (ofdm->transmission_mode) { 233/* settings here are for 27.7MHz */
216 case TRANSMISSION_MODE_2K: fft = DIB3000_TRANSMISSION_MODE_2K; break; 234 switch (bw) {
217 case TRANSMISSION_MODE_8K: fft = DIB3000_TRANSMISSION_MODE_8K; break; 235 case BANDWIDTH_8_MHZ:
218 case TRANSMISSION_MODE_AUTO: break; 236 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
219 default: return -EINVAL; 237 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
220 } 238 break;
221 switch (ofdm->guard_interval) {
222 case GUARD_INTERVAL_1_32: guard = DIB3000_GUARD_TIME_1_32; break;
223 case GUARD_INTERVAL_1_16: guard = DIB3000_GUARD_TIME_1_16; break;
224 case GUARD_INTERVAL_1_8: guard = DIB3000_GUARD_TIME_1_8; break;
225 case GUARD_INTERVAL_1_4: guard = DIB3000_GUARD_TIME_1_4; break;
226 case GUARD_INTERVAL_AUTO: break;
227 default: return -EINVAL;
228 }
229 switch (ofdm->constellation) {
230 case QPSK: qam = DIB3000_CONSTELLATION_QPSK; break;
231 case QAM_16: qam = DIB3000_CONSTELLATION_16QAM; break;
232 case QAM_64: qam = DIB3000_CONSTELLATION_64QAM; break;
233 case QAM_AUTO: break;
234 default: return -EINVAL;
235 }
236 switch (ofdm->hierarchy_information) {
237 case HIERARCHY_NONE: /* fall through */
238 case HIERARCHY_1: alpha = DIB3000_ALPHA_1; break;
239 case HIERARCHY_2: alpha = DIB3000_ALPHA_2; break;
240 case HIERARCHY_4: alpha = DIB3000_ALPHA_4; break;
241 case HIERARCHY_AUTO: break;
242 default: return -EINVAL;
243 }
244 if (ofdm->hierarchy_information == HIERARCHY_NONE) {
245 hrch = DIB3000_HRCH_OFF;
246 sel_hp = DIB3000_SELECT_HP;
247 fe_cr = ofdm->code_rate_HP;
248 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
249 hrch = DIB3000_HRCH_ON;
250 sel_hp = DIB3000_SELECT_LP;
251 fe_cr = ofdm->code_rate_LP;
252 }
253 switch (fe_cr) {
254 case FEC_1_2: cr = DIB3000_FEC_1_2; break;
255 case FEC_2_3: cr = DIB3000_FEC_2_3; break;
256 case FEC_3_4: cr = DIB3000_FEC_3_4; break;
257 case FEC_5_6: cr = DIB3000_FEC_5_6; break;
258 case FEC_7_8: cr = DIB3000_FEC_7_8; break;
259 case FEC_NONE: break;
260 case FEC_AUTO: break;
261 default: return -EINVAL;
262 }
263 239
264 wr(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_PARM(alpha,qam,guard,fft)); 240 case BANDWIDTH_7_MHZ:
265 wr(DIB3000MC_REG_HRCH_PARM,DIB3000MC_HRCH_PARM(sel_hp,cr,hrch)); 241 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
242 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
243 break;
266 244
267 switch (fep->inversion) { 245 case BANDWIDTH_6_MHZ:
268 case INVERSION_OFF: 246 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
269 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF); 247 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
270 break; 248 break;
271 case INVERSION_AUTO: /* fall through */ 249
272 case INVERSION_ON: 250 case 255 /* BANDWIDTH_5_MHZ */:
273 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON); 251 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
252 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
274 break; 253 break;
275 default: 254
276 return -EINVAL; 255 default: return -EINVAL;
277 } 256 }
278 257
279 seq = dib3000_seq 258 for (reg = 6; reg < 12; reg++)
280 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO] 259 dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
281 [ofdm->guard_interval == GUARD_INTERVAL_AUTO] 260 dib3000mc_write_word(state, 12, 0x0000);
282 [fep->inversion == INVERSION_AUTO]; 261 dib3000mc_write_word(state, 13, 0x03e8);
283 262 dib3000mc_write_word(state, 14, 0x0000);
284 deb_setf("seq? %d\n", seq); 263 dib3000mc_write_word(state, 15, 0x03f2);
285 wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS(seq,1)); 264 dib3000mc_write_word(state, 16, 0x0001);
286 *auto_val = ofdm->constellation == QAM_AUTO || 265 dib3000mc_write_word(state, 17, 0xb0d0);
287 ofdm->hierarchy_information == HIERARCHY_AUTO || 266 // P_sec_len
288 ofdm->guard_interval == GUARD_INTERVAL_AUTO || 267 dib3000mc_write_word(state, 18, 0x0393);
289 ofdm->transmission_mode == TRANSMISSION_MODE_AUTO || 268 dib3000mc_write_word(state, 19, 0x8700);
290 fe_cr == FEC_AUTO ||
291 fep->inversion == INVERSION_AUTO;
292 return 0;
293}
294 269
295static int dib3000mc_get_frontend(struct dvb_frontend* fe, 270 for (reg = 55; reg < 58; reg++)
296 struct dvb_frontend_parameters *fep) 271 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
297{
298 struct dib3000_state* state = fe->demodulator_priv;
299 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
300 fe_code_rate_t *cr;
301 u16 tps_val,cr_val;
302 int inv_test1,inv_test2;
303 u32 dds_val, threshold = 0x1000000;
304
305 if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507))
306 return 0;
307
308 dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB);
309 deb_getf("DDS_FREQ: %6x\n",dds_val);
310 if (dds_val < threshold)
311 inv_test1 = 0;
312 else if (dds_val == threshold)
313 inv_test1 = 1;
314 else
315 inv_test1 = 2;
316
317 dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB);
318 deb_getf("DDS_SET_FREQ: %6x\n",dds_val);
319 if (dds_val < threshold)
320 inv_test2 = 0;
321 else if (dds_val == threshold)
322 inv_test2 = 1;
323 else
324 inv_test2 = 2;
325 272
326 fep->inversion = 273 // Timing configuration
327 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) || 274 dib3000mc_set_timing(state, 0, bw, 0);
328 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
329 INVERSION_ON : INVERSION_OFF;
330 275
331 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion); 276 return 0;
277}
332 278
333 fep->frequency = state->last_tuned_freq; 279static u16 impulse_noise_val[29] =
334 fep->u.ofdm.bandwidth= state->last_tuned_bw;
335 280
336 tps_val = rd(DIB3000MC_REG_TUNING_PARM); 281{
282 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
283 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
284 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
285};
337 286
338 switch (DIB3000MC_TP_QAM(tps_val)) { 287static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
339 case DIB3000_CONSTELLATION_QPSK: 288{
340 deb_getf("QPSK "); 289 u16 i;
341 ofdm->constellation = QPSK; 290 for (i = 58; i < 87; i++)
342 break; 291 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
343 case DIB3000_CONSTELLATION_16QAM: 292
344 deb_getf("QAM16 "); 293 if (nfft == 1) {
345 ofdm->constellation = QAM_16; 294 dib3000mc_write_word(state, 58, 0x3b);
346 break; 295 dib3000mc_write_word(state, 84, 0x00);
347 case DIB3000_CONSTELLATION_64QAM: 296 dib3000mc_write_word(state, 85, 0x8200);
348 deb_getf("QAM64 ");
349 ofdm->constellation = QAM_64;
350 break;
351 default:
352 err("Unexpected constellation returned by TPS (%d)", tps_val);
353 break;
354 } 297 }
355 298
356 if (DIB3000MC_TP_HRCH(tps_val)) { 299 dib3000mc_write_word(state, 34, 0x1294);
357 deb_getf("HRCH ON "); 300 dib3000mc_write_word(state, 35, 0x1ff8);
358 cr = &ofdm->code_rate_LP; 301 if (mode == 1)
359 ofdm->code_rate_HP = FEC_NONE; 302 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
360 switch (DIB3000MC_TP_ALPHA(tps_val)) { 303}
361 case DIB3000_ALPHA_0: 304
362 deb_getf("HIERARCHY_NONE "); 305static int dib3000mc_init(struct dvb_frontend *demod)
363 ofdm->hierarchy_information = HIERARCHY_NONE; 306{
364 break; 307 struct dib3000mc_state *state = demod->demodulator_priv;
365 case DIB3000_ALPHA_1: 308 struct dibx000_agc_config *agc = state->cfg->agc;
366 deb_getf("HIERARCHY_1 "); 309
367 ofdm->hierarchy_information = HIERARCHY_1; 310 // Restart Configuration
368 break; 311 dib3000mc_write_word(state, 1027, 0x8000);
369 case DIB3000_ALPHA_2: 312 dib3000mc_write_word(state, 1027, 0x0000);
370 deb_getf("HIERARCHY_2 "); 313
371 ofdm->hierarchy_information = HIERARCHY_2; 314 // power up the demod + mobility configuration
372 break; 315 dib3000mc_write_word(state, 140, 0x0000);
373 case DIB3000_ALPHA_4: 316 dib3000mc_write_word(state, 1031, 0);
374 deb_getf("HIERARCHY_4 "); 317
375 ofdm->hierarchy_information = HIERARCHY_4; 318 if (state->cfg->mobile_mode) {
376 break; 319 dib3000mc_write_word(state, 139, 0x0000);
377 default: 320 dib3000mc_write_word(state, 141, 0x0000);
378 err("Unexpected ALPHA value returned by TPS (%d)", tps_val); 321 dib3000mc_write_word(state, 175, 0x0002);
379 break; 322 dib3000mc_write_word(state, 1032, 0x0000);
380 }
381 cr_val = DIB3000MC_TP_FEC_CR_LP(tps_val);
382 } else { 323 } else {
383 deb_getf("HRCH OFF "); 324 dib3000mc_write_word(state, 139, 0x0001);
384 cr = &ofdm->code_rate_HP; 325 dib3000mc_write_word(state, 141, 0x0000);
385 ofdm->code_rate_LP = FEC_NONE; 326 dib3000mc_write_word(state, 175, 0x0000);
386 ofdm->hierarchy_information = HIERARCHY_NONE; 327 dib3000mc_write_word(state, 1032, 0x012C);
387 cr_val = DIB3000MC_TP_FEC_CR_HP(tps_val);
388 } 328 }
329 dib3000mc_write_word(state, 1033, 0);
389 330
390 switch (cr_val) { 331 // P_clk_cfg
391 case DIB3000_FEC_1_2: 332 dib3000mc_write_word(state, 1037, 12592);
392 deb_getf("FEC_1_2 ");
393 *cr = FEC_1_2;
394 break;
395 case DIB3000_FEC_2_3:
396 deb_getf("FEC_2_3 ");
397 *cr = FEC_2_3;
398 break;
399 case DIB3000_FEC_3_4:
400 deb_getf("FEC_3_4 ");
401 *cr = FEC_3_4;
402 break;
403 case DIB3000_FEC_5_6:
404 deb_getf("FEC_5_6 ");
405 *cr = FEC_4_5;
406 break;
407 case DIB3000_FEC_7_8:
408 deb_getf("FEC_7_8 ");
409 *cr = FEC_7_8;
410 break;
411 default:
412 err("Unexpected FEC returned by TPS (%d)", tps_val);
413 break;
414 }
415 333
416 switch (DIB3000MC_TP_GUARD(tps_val)) { 334 // other configurations
417 case DIB3000_GUARD_TIME_1_32:
418 deb_getf("GUARD_INTERVAL_1_32 ");
419 ofdm->guard_interval = GUARD_INTERVAL_1_32;
420 break;
421 case DIB3000_GUARD_TIME_1_16:
422 deb_getf("GUARD_INTERVAL_1_16 ");
423 ofdm->guard_interval = GUARD_INTERVAL_1_16;
424 break;
425 case DIB3000_GUARD_TIME_1_8:
426 deb_getf("GUARD_INTERVAL_1_8 ");
427 ofdm->guard_interval = GUARD_INTERVAL_1_8;
428 break;
429 case DIB3000_GUARD_TIME_1_4:
430 deb_getf("GUARD_INTERVAL_1_4 ");
431 ofdm->guard_interval = GUARD_INTERVAL_1_4;
432 break;
433 default:
434 err("Unexpected Guard Time returned by TPS (%d)", tps_val);
435 break;
436 }
437 335
438 switch (DIB3000MC_TP_FFT(tps_val)) { 336 // P_ctrl_sfreq
439 case DIB3000_TRANSMISSION_MODE_2K: 337 dib3000mc_write_word(state, 33, (5 << 0));
440 deb_getf("TRANSMISSION_MODE_2K "); 338 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
441 ofdm->transmission_mode = TRANSMISSION_MODE_2K; 339
442 break; 340 // Phase noise control
443 case DIB3000_TRANSMISSION_MODE_8K: 341 // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
444 deb_getf("TRANSMISSION_MODE_8K "); 342 dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
445 ofdm->transmission_mode = TRANSMISSION_MODE_8K; 343
446 break; 344 if (state->cfg->phase_noise_mode == 0)
447 default: 345 dib3000mc_write_word(state, 111, 0x00);
448 err("unexpected transmission mode return by TPS (%d)", tps_val); 346 else
449 break; 347 dib3000mc_write_word(state, 111, 0x02);
450 } 348
451 deb_getf("\n"); 349 // P_agc_global
350 dib3000mc_write_word(state, 50, 0x8000);
351
352 // agc setup misc
353 dib3000mc_setup_pwm3_state(state);
354
355 // P_agc_counter_lock
356 dib3000mc_write_word(state, 53, 0x87);
357 // P_agc_counter_unlock
358 dib3000mc_write_word(state, 54, 0x87);
359
360 /* agc */
361 dib3000mc_write_word(state, 36, state->cfg->max_time);
362 dib3000mc_write_word(state, 37, agc->setup);
363 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
364 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
365
366 // set_agc_loop_Bw
367 dib3000mc_write_word(state, 40, 0x0179);
368 dib3000mc_write_word(state, 41, 0x03f0);
369
370 dib3000mc_write_word(state, 42, agc->agc1_max);
371 dib3000mc_write_word(state, 43, agc->agc1_min);
372 dib3000mc_write_word(state, 44, agc->agc2_max);
373 dib3000mc_write_word(state, 45, agc->agc2_min);
374 dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
375 dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
376 dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
377 dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
378
379// Begin: TimeOut registers
380 // P_pha3_thres
381 dib3000mc_write_word(state, 110, 3277);
382 // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
383 dib3000mc_write_word(state, 26, 0x6680);
384 // lock_mask0
385 dib3000mc_write_word(state, 1, 4);
386 // lock_mask1
387 dib3000mc_write_word(state, 2, 4);
388 // lock_mask2
389 dib3000mc_write_word(state, 3, 0x1000);
390 // P_search_maxtrial=1
391 dib3000mc_write_word(state, 5, 1);
392
393 dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
394
395 // div_lock_mask
396 dib3000mc_write_word(state, 4, 0x814);
397
398 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
399 dib3000mc_write_word(state, 22, 0x463d);
400
401 // Spurious rm cfg
402 // P_cspu_regul, P_cspu_win_cut
403 dib3000mc_write_word(state, 120, 0x200f);
404 // P_adp_selec_monit
405 dib3000mc_write_word(state, 134, 0);
406
407 // Fec cfg
408 dib3000mc_write_word(state, 195, 0x10);
409
410 // diversity register: P_dvsy_sync_wait..
411 dib3000mc_write_word(state, 180, 0x2FF0);
412
413 // Impulse noise configuration
414 dib3000mc_set_impulse_noise(state, 0, 1);
415
416 // output mode set-up
417 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
418
419 /* close the i2c-gate */
420 dib3000mc_write_word(state, 769, (1 << 7) );
452 421
453 return 0; 422 return 0;
454} 423}
455 424
456static int dib3000mc_set_frontend(struct dvb_frontend* fe, 425static int dib3000mc_sleep(struct dvb_frontend *demod)
457 struct dvb_frontend_parameters *fep, int tuner)
458{ 426{
459 struct dib3000_state* state = fe->demodulator_priv; 427 struct dib3000mc_state *state = demod->demodulator_priv;
460 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
461 int search_state,auto_val;
462 u16 val;
463 428
464 if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */ 429 dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003);
465 fe->ops.tuner_ops.set_params(fe, fep); 430 dib3000mc_write_word(state, 1031, 0xFFFF);
466 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 431 dib3000mc_write_word(state, 1032, 0xFFFF);
467 432 dib3000mc_write_word(state, 1033, 0xFFF4); // **** Bin2
468 state->last_tuned_freq = fep->frequency;
469 // if (!scanboost) {
470 dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth);
471 dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0);
472 state->last_tuned_bw = ofdm->bandwidth;
473
474 wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
475 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC);
476 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
477
478 /* Default cfg isi offset adp */
479 wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]);
480
481 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT);
482 dib3000mc_set_adp_cfg(state,ofdm->constellation);
483 wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133);
484
485 wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
486 /* power smoothing */
487 if (ofdm->bandwidth != BANDWIDTH_8_MHZ) {
488 wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]);
489 } else {
490 wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]);
491 }
492 auto_val = 0;
493 dib3000mc_set_general_cfg(state,fep,&auto_val);
494 dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
495
496 val = rd(DIB3000MC_REG_DEMOD_PARM);
497 wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON);
498 wr(DIB3000MC_REG_DEMOD_PARM,val);
499 // }
500 msleep(70);
501
502 /* something has to be auto searched */
503 if (auto_val) {
504 int as_count=0;
505
506 deb_setf("autosearch enabled.\n");
507
508 val = rd(DIB3000MC_REG_DEMOD_PARM);
509 wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
510 wr(DIB3000MC_REG_DEMOD_PARM,val);
511
512 while ((search_state = dib3000_search_status(
513 rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100)
514 msleep(10);
515
516 deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count);
517
518 if (search_state == 1) {
519 struct dvb_frontend_parameters feps;
520 if (dib3000mc_get_frontend(fe, &feps) == 0) {
521 deb_setf("reading tuning data from frontend succeeded.\n");
522 return dib3000mc_set_frontend(fe, &feps, 0);
523 }
524 }
525 } else {
526 dib3000mc_set_impulse_noise(state,0,ofdm->transmission_mode,ofdm->bandwidth);
527 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
528 dib3000mc_set_adp_cfg(state,ofdm->constellation);
529
530 /* set_offset_cfg */
531 wr_foreach(dib3000mc_reg_offset,
532 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
533 }
534 } else { /* second call, after autosearch (fka: set_WithKnownParams) */
535// dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth);
536
537 auto_val = 0;
538 dib3000mc_set_general_cfg(state,fep,&auto_val);
539 if (auto_val)
540 deb_info("auto_val is true, even though an auto search was already performed.\n");
541
542 dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
543
544 val = rd(DIB3000MC_REG_DEMOD_PARM);
545 wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
546 wr(DIB3000MC_REG_DEMOD_PARM,val);
547 433
548 msleep(30); 434 return 0;
435}
549 436
550 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE); 437static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
551 dib3000mc_set_adp_cfg(state,ofdm->constellation); 438{
552 wr_foreach(dib3000mc_reg_offset, 439 u16 cfg[4] = { 0 },reg;
553 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]); 440 switch (qam) {
441 case 0:
442 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
443 break;
444 case 1:
445 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
446 break;
447 case 2:
448 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
449 break;
554 } 450 }
555 return 0; 451 for (reg = 129; reg < 133; reg++)
452 dib3000mc_write_word(state, reg, cfg[reg - 129]);
556} 453}
557 454
558static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) 455static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq)
559{ 456{
560 struct dib3000_state *state = fe->demodulator_priv; 457 u16 tmp;
561 deb_info("init start\n");
562
563 state->timing_offset = 0;
564 state->timing_offset_comp_done = 0;
565 458
566 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG); 459 dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0);
567 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
568 wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_UP);
569 wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_PUP_MOBILE);
570 wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_UP);
571 wr(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_INIT);
572 460
573 wr(DIB3000MC_REG_RST_UNC,DIB3000MC_RST_UNC_OFF); 461// if (boost)
574 wr(DIB3000MC_REG_UNK_19,DIB3000MC_UNK_19); 462// dib3000mc_write_word(state, 100, (11 << 6) + 6);
463// else
464 dib3000mc_write_word(state, 100, (16 << 6) + 9);
575 465
576 wr(33,5); 466 dib3000mc_write_word(state, 1027, 0x0800);
577 wr(36,81); 467 dib3000mc_write_word(state, 1027, 0x0000);
578 wr(DIB3000MC_REG_UNK_88,DIB3000MC_UNK_88);
579 468
580 wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99); 469 //Default cfg isi offset adp
581 wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */ 470 dib3000mc_write_word(state, 26, 0x6680);
471 dib3000mc_write_word(state, 29, 0x1273);
472 dib3000mc_write_word(state, 33, 5);
473 dib3000mc_set_adp_cfg(state, 1);
474 dib3000mc_write_word(state, 133, 15564);
582 475
583 /* mobile mode - portable reception */ 476 dib3000mc_write_word(state, 12 , 0x0);
584 wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]); 477 dib3000mc_write_word(state, 13 , 0x3e8);
478 dib3000mc_write_word(state, 14 , 0x0);
479 dib3000mc_write_word(state, 15 , 0x3f2);
585 480
586/* TUNER_PANASONIC_ENV57H12D5: */ 481 dib3000mc_write_word(state, 93,0);
587 wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth); 482 dib3000mc_write_word(state, 94,0);
588 wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general); 483 dib3000mc_write_word(state, 95,0);
589 wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]); 484 dib3000mc_write_word(state, 96,0);
485 dib3000mc_write_word(state, 97,0);
486 dib3000mc_write_word(state, 98,0);
590 487
591 wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110); 488 dib3000mc_set_impulse_noise(state, 0, chan->nfft);
592 wr(26,0x6680);
593 wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1);
594 wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2);
595 wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3);
596 wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT);
597 489
598 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz); 490 tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
599 wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general); 491 dib3000mc_write_word(state, 0, tmp);
600 492
601 wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4); 493 dib3000mc_write_word(state, 5, seq);
602 494
603 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF); 495 tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp);
604 wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB); 496 if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp))
497 tmp |= chan->vit_code_rate_hp << 1;
498 else
499 tmp |= chan->vit_code_rate_lp << 1;
500 dib3000mc_write_word(state, 181, tmp);
605 501
606 dib3000mc_set_timing(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ); 502 // diversity synchro delay
607// wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]); 503 tmp = dib3000mc_read_word(state, 180) & 0x000f;
504 tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin
505 dib3000mc_write_word(state, 180, tmp);
608 506
609 wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120); 507 // restart demod
610 wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134); 508 tmp = dib3000mc_read_word(state, 0);
611 wr(DIB3000MC_REG_FEC_CFG,DIB3000MC_FEC_CFG); 509 dib3000mc_write_word(state, 0, tmp | (1 << 9));
510 dib3000mc_write_word(state, 0, tmp);
612 511
613 wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF); 512 msleep(30);
614 513
615 dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ); 514 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft);
515}
616 516
617/* output mode control, just the MPEG2_SLAVE */ 517static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan)
618// set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE); 518{
619 wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE); 519 struct dib3000mc_state *state = demod->demodulator_priv;
620 wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE); 520 u16 reg;
621 wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE); 521// u32 val;
622 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE); 522 struct dibx000_ofdm_channel fchan;
623 523
624/* MPEG2_PARALLEL_CONTINUOUS_CLOCK 524 INIT_OFDM_CHANNEL(&fchan);
625 wr(DIB3000MC_REG_OUTMODE, 525 fchan = *chan;
626 DIB3000MC_SET_OUTMODE(DIB3000MC_OM_PAR_CONT_CLK,
627 rd(DIB3000MC_REG_OUTMODE)));
628 526
629 wr(DIB3000MC_REG_SMO_MODE,
630 DIB3000MC_SMO_MODE_DEFAULT |
631 DIB3000MC_SMO_MODE_188);
632 527
633 wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_DEFAULT); 528 /* a channel for autosearch */
634 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON); 529 reg = 0;
635*/ 530 if (chan->nfft == -1 && chan->guard == -1) reg = 7;
531 if (chan->nfft == -1 && chan->guard != -1) reg = 2;
532 if (chan->nfft != -1 && chan->guard == -1) reg = 3;
636 533
637/* diversity */ 534 fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2;
638 wr(DIB3000MC_REG_DIVERSITY1,DIB3000MC_DIVERSITY1_DEFAULT); 535 fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2;
639 wr(DIB3000MC_REG_DIVERSITY2,DIB3000MC_DIVERSITY2_DEFAULT); 536 fchan.vit_hrch = 0; fchan.vit_select_hp = 1;
640 537
641 set_and(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF); 538 dib3000mc_set_channel_cfg(state, &fchan, reg);
642 539
643 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); 540 reg = dib3000mc_read_word(state, 0);
541 dib3000mc_write_word(state, 0, reg | (1 << 8));
542 dib3000mc_write_word(state, 0, reg);
644 543
645 deb_info("init end\n");
646 return 0; 544 return 0;
647} 545}
648static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat) 546
547static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
649{ 548{
650 struct dib3000_state* state = fe->demodulator_priv; 549 struct dib3000mc_state *state = demod->demodulator_priv;
651 u16 lock = rd(DIB3000MC_REG_LOCKING); 550 u16 irq_pending = dib3000mc_read_word(state, 511);
652 551
653 *stat = 0; 552 if (irq_pending & 0x1) // failed
654 if (DIB3000MC_AGC_LOCK(lock)) 553 return 1;
655 *stat |= FE_HAS_SIGNAL;
656 if (DIB3000MC_CARRIER_LOCK(lock))
657 *stat |= FE_HAS_CARRIER;
658 if (DIB3000MC_TPS_LOCK(lock))
659 *stat |= FE_HAS_VITERBI;
660 if (DIB3000MC_MPEG_SYNC_LOCK(lock))
661 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
662 554
663 deb_stat("actual status is %2x fifo_level: %x,244: %x, 206: %x, 207: %x, 1040: %x\n",*stat,rd(510),rd(244),rd(206),rd(207),rd(1040)); 555 if (irq_pending & 0x2) // succeeded
556 return 2;
664 557
665 return 0; 558 return 0; // still pending
666} 559}
667 560
668static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber) 561static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
669{ 562{
670 struct dib3000_state* state = fe->demodulator_priv; 563 struct dib3000mc_state *state = demod->demodulator_priv;
671 *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB)); 564
565 // ** configure demod **
566 dib3000mc_set_channel_cfg(state, ch, 0);
567
568 // activates isi
569 dib3000mc_write_word(state, 29, 0x1073);
570
571 dib3000mc_set_adp_cfg(state, (u8)ch->nqam);
572
573 if (ch->nfft == 1) {
574 dib3000mc_write_word(state, 26, 38528);
575 dib3000mc_write_word(state, 33, 8);
576 } else {
577 dib3000mc_write_word(state, 26, 30336);
578 dib3000mc_write_word(state, 33, 6);
579 }
580
581 // if (lock)
582 // dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
583
672 return 0; 584 return 0;
673} 585}
674 586
675static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) 587static int dib3000mc_demod_output_mode(struct dvb_frontend *demod, int mode)
676{ 588{
677 struct dib3000_state* state = fe->demodulator_priv; 589 struct dib3000mc_state *state = demod->demodulator_priv;
678 590 return dib3000mc_set_output_mode(state, mode);
679 *unc = rd(DIB3000MC_REG_PACKET_ERRORS);
680 return 0;
681} 591}
682 592
683/* see dib3000mb.c for calculation comments */ 593static int dib3000mc_i2c_enumeration(struct dvb_frontend *demod[], int no_of_demods, u8 default_addr)
684static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
685{ 594{
686 struct dib3000_state* state = fe->demodulator_priv; 595 struct dib3000mc_state *st;
687 u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB); 596 int k,ret=0;
688 *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f); 597 u8 new_addr;
598
599 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
600
601 for (k = no_of_demods-1; k >= 0; k--) {
602 st = demod[k]->demodulator_priv;
603
604 /* designated i2c address */
605 new_addr = DIB3000MC_I2C_ADDRESS[k];
606
607 st->i2c_addr = new_addr;
608 if (dib3000mc_identify(st) != 0) {
609 st->i2c_addr = default_addr;
610 if (dib3000mc_identify(st) != 0) {
611 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
612 return -EINVAL;
613 }
614 }
615
616 /* turn on div_out */
617 dib3000mc_demod_output_mode(demod[k], OUTMODE_MPEG2_PAR_CONT_CLK);
618
619 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
620 ret |= dib3000mc_write_word(st, 1024, (new_addr << 3) | 0x1);
621 st->i2c_addr = new_addr;
622 }
623
624 for (k = 0; k < no_of_demods; k++) {
625 st = demod[k]->demodulator_priv;
626
627 ret |= dib3000mc_write_word(st, 1024, st->i2c_addr << 3);
689 628
690 deb_stat("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff); 629 /* turn off data output */
630 dib3000mc_demod_output_mode(demod[k],OUTMODE_HIGH_Z);
631 dib3000mc_write_word(st, 769, (1 << 7) );
632
633 }
691 return 0; 634 return 0;
692} 635}
693 636
694/* see dib3000mb.c for calculation comments */ 637struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
695static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
696{ 638{
697 struct dib3000_state* state = fe->demodulator_priv; 639 struct dib3000mc_state *st = demod->demodulator_priv;
698 u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB), 640 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
699 val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB); 641}
700 u16 sig,noise;
701 642
702 sig = (((val >> 6) & 0xff) << 8) + (val & 0x3f); 643EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
703 noise = (((val >> 4) & 0xff) << 8) + ((val & 0xf) << 2) + ((val2 >> 14) & 0x3); 644
704 if (noise == 0) 645static int dib3000mc_get_frontend(struct dvb_frontend* fe,
705 *snr = 0xffff; 646 struct dvb_frontend_parameters *fep)
706 else 647{
707 *snr = (u16) sig/noise; 648 struct dib3000mc_state *state = fe->demodulator_priv;
649 u16 tps = dib3000mc_read_word(state,458);
650
651 fep->inversion = INVERSION_AUTO;
652
653 fep->u.ofdm.bandwidth = state->current_bandwidth;
654
655 switch ((tps >> 8) & 0x1) {
656 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
657 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
658 }
659
660 switch (tps & 0x3) {
661 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
662 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
663 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
664 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
665 }
666
667 switch ((tps >> 13) & 0x3) {
668 case 0: fep->u.ofdm.constellation = QPSK; break;
669 case 1: fep->u.ofdm.constellation = QAM_16; break;
670 case 2:
671 default: fep->u.ofdm.constellation = QAM_64; break;
672 }
673
674 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
675 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
676
677 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
678 switch ((tps >> 5) & 0x7) {
679 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
680 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
681 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
682 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
683 case 7:
684 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
685
686 }
687
688 switch ((tps >> 2) & 0x7) {
689 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
690 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
691 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
692 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
693 case 7:
694 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
695 }
708 696
709 deb_stat("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff);
710 deb_stat("noise: mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff);
711 deb_stat("snr: %d\n",*snr);
712 return 0; 697 return 0;
713} 698}
714 699
715static int dib3000mc_sleep(struct dvb_frontend* fe) 700static int dib3000mc_set_frontend(struct dvb_frontend* fe,
701 struct dvb_frontend_parameters *fep)
716{ 702{
717 struct dib3000_state* state = fe->demodulator_priv; 703 struct dib3000mc_state *state = fe->demodulator_priv;
704 struct dibx000_ofdm_channel ch;
718 705
719 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN); 706 INIT_OFDM_CHANNEL(&ch);
720 wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN); 707 FEP2DIB(fep,&ch);
721 wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_POWER_DOWN); 708
722 wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_DOWN); 709 state->current_bandwidth = fep->u.ofdm.bandwidth;
723 return 0; 710 dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth);
711
712 if (fe->ops.tuner_ops.set_params) {
713 fe->ops.tuner_ops.set_params(fe, fep);
714 msleep(100);
715 }
716
717 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
718 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
719 fep->u.ofdm.constellation == QAM_AUTO ||
720 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
721 int i = 100, found;
722
723 dib3000mc_autosearch_start(fe, &ch);
724 do {
725 msleep(1);
726 found = dib3000mc_autosearch_is_irq(fe);
727 } while (found == 0 && i--);
728
729 dprintk("autosearch returns: %d\n",found);
730 if (found == 0 || found == 1)
731 return 0; // no channel found
732
733 dib3000mc_get_frontend(fe, fep);
734 FEP2DIB(fep,&ch);
735 }
736
737 /* make this a config parameter */
738 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
739
740 return dib3000mc_tune(fe, &ch);
724} 741}
725 742
726static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) 743static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
727{ 744{
728 tune->min_delay_ms = 1000; 745 struct dib3000mc_state *state = fe->demodulator_priv;
746 u16 lock = dib3000mc_read_word(state, 509);
747
748 *stat = 0;
749
750 if (lock & 0x8000)
751 *stat |= FE_HAS_SIGNAL;
752 if (lock & 0x3000)
753 *stat |= FE_HAS_CARRIER;
754 if (lock & 0x0100)
755 *stat |= FE_HAS_VITERBI;
756 if (lock & 0x0010)
757 *stat |= FE_HAS_SYNC;
758 if (lock & 0x0008)
759 *stat |= FE_HAS_LOCK;
760
729 return 0; 761 return 0;
730} 762}
731 763
732static int dib3000mc_fe_init_nonmobile(struct dvb_frontend* fe) 764static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
733{ 765{
734 return dib3000mc_fe_init(fe, 0); 766 struct dib3000mc_state *state = fe->demodulator_priv;
767 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
768 return 0;
735} 769}
736 770
737static int dib3000mc_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) 771static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
738{ 772{
739 return dib3000mc_set_frontend(fe, fep, 1); 773 struct dib3000mc_state *state = fe->demodulator_priv;
774 *unc = dib3000mc_read_word(state, 508);
775 return 0;
740} 776}
741 777
742static void dib3000mc_release(struct dvb_frontend* fe) 778static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
743{ 779{
744 struct dib3000_state *state = fe->demodulator_priv; 780 struct dib3000mc_state *state = fe->demodulator_priv;
745 kfree(state); 781 u16 val = dib3000mc_read_word(state, 392);
782 *strength = 65535 - val;
783 return 0;
746} 784}
747 785
748/* pid filter and transfer stuff */ 786static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
749static int dib3000mc_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
750{ 787{
751 struct dib3000_state *state = fe->demodulator_priv; 788 *snr = 0x0000;
752 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
753 wr(index+DIB3000MC_REG_FIRST_PID,pid);
754 return 0; 789 return 0;
755} 790}
756 791
757static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff) 792static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
758{ 793{
759 struct dib3000_state *state = fe->demodulator_priv; 794 tune->min_delay_ms = 1000;
760 u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
761
762 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
763
764 if (onoff) {
765 deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
766 wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
767 } else {
768 deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
769 wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
770 }
771 return 0; 795 return 0;
772} 796}
773 797
774static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) 798static void dib3000mc_release(struct dvb_frontend *fe)
775{ 799{
776 struct dib3000_state *state = fe->demodulator_priv; 800 struct dib3000mc_state *state = fe->demodulator_priv;
777 u16 tmp = rd(DIB3000MC_REG_SMO_MODE); 801 dibx000_exit_i2c_master(&state->i2c_master);
778 802 kfree(state);
779 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
780
781 if (onoff) {
782 wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE);
783 } else {
784 wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE);
785 }
786 return 0;
787} 803}
788 804
789static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) 805int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
790{ 806{
791 struct dib3000_state *state = fe->demodulator_priv; 807 struct dib3000mc_state *state = fe->demodulator_priv;
792 if (onoff) { 808 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
793 wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
794 } else {
795 wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
796 }
797 return 0; 809 return 0;
798} 810}
811EXPORT_SYMBOL(dib3000mc_pid_control);
799 812
800static int dib3000mc_demod_init(struct dib3000_state *state) 813int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
801{ 814{
802 u16 default_addr = 0x0a; 815 struct dib3000mc_state *state = fe->demodulator_priv;
803 /* first init */ 816 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
804 if (state->config.demod_address != default_addr) { 817 tmp |= (onoff << 4);
805 deb_info("initializing the demod the first time. Setting demod addr to 0x%x\n",default_addr); 818 return dib3000mc_write_word(state, 206, tmp);
806 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
807 wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK);
808
809 wr(DIB3000MC_REG_RST_I2C_ADDR,
810 DIB3000MC_DEMOD_ADDR(default_addr) |
811 DIB3000MC_DEMOD_ADDR_ON);
812
813 state->config.demod_address = default_addr;
814
815 wr(DIB3000MC_REG_RST_I2C_ADDR,
816 DIB3000MC_DEMOD_ADDR(default_addr));
817 } else
818 deb_info("demod is already initialized. Demod addr: 0x%x\n",state->config.demod_address);
819 return 0;
820} 819}
820EXPORT_SYMBOL(dib3000mc_pid_parse);
821 821
822void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
823{
824 struct dib3000mc_state *state = fe->demodulator_priv;
825 state->cfg = cfg;
826}
827EXPORT_SYMBOL(dib3000mc_set_config);
822 828
823static struct dvb_frontend_ops dib3000mc_ops; 829static struct dvb_frontend_ops dib3000mc_ops;
824 830
825struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, 831int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr, u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[])
826 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
827{ 832{
828 struct dib3000_state* state = NULL; 833 struct dib3000mc_state *st;
829 u16 devid; 834 int k, num=0;
830 835
831 /* allocate memory for the internal state */ 836 if (no_of_demods < 1)
832 state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL); 837 return -EINVAL;
833 if (state == NULL)
834 goto error;
835 838
836 /* setup the state */ 839 for (k = 0; k < no_of_demods; k++) {
837 state->i2c = i2c; 840 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
838 memcpy(&state->config,config,sizeof(struct dib3000_config)); 841 if (st == NULL)
842 goto error;
839 843
840 /* check for the correct demod */ 844 num++;
841 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
842 goto error;
843 845
844 devid = rd(DIB3000_REG_DEVICE_ID); 846 st->cfg = &cfg[k];
845 if (devid != DIB3000MC_DEVICE_ID && devid != DIB3000P_DEVICE_ID) 847 // st->gpio_val = cfg[k].gpio_val;
846 goto error; 848 // st->gpio_dir = cfg[k].gpio_dir;
849 st->i2c_adap = i2c_adap;
847 850
848 switch (devid) { 851 demod[k] = &st->demod;
849 case DIB3000MC_DEVICE_ID: 852 demod[k]->demodulator_priv = st;
850 info("Found a DiBcom 3000M-C, interesting..."); 853 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
851 break;
852 case DIB3000P_DEVICE_ID:
853 info("Found a DiBcom 3000P.");
854 break;
855 }
856 854
857 /* create dvb_frontend */ 855// INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st);
858 memcpy(&state->frontend.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); 856// demod[k]->register_access = &st->register_access;
859 state->frontend.demodulator_priv = state; 857 }
860 858
861 /* set the xfer operations */ 859 if (do_i2c_enum) {
862 xfer_ops->pid_parse = dib3000mc_pid_parse; 860 if (dib3000mc_i2c_enumeration(demod,no_of_demods,default_addr) != 0)
863 xfer_ops->fifo_ctrl = dib3000mc_fifo_control; 861 goto error;
864 xfer_ops->pid_ctrl = dib3000mc_pid_control; 862 } else {
865 xfer_ops->tuner_pass_ctrl = dib3000mc_tuner_pass_ctrl; 863 st = demod[0]->demodulator_priv;
864 st->i2c_addr = default_addr;
865 if (dib3000mc_identify(st) != 0)
866 goto error;
867 }
866 868
867 dib3000mc_demod_init(state); 869 for (k = 0; k < num; k++) {
870 st = demod[k]->demodulator_priv;
871 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
872 }
868 873
869 return &state->frontend; 874 return 0;
870 875
871error: 876error:
872 kfree(state); 877 for (k = 0; k < num; k++) {
873 return NULL; 878 kfree(demod[k]->demodulator_priv);
879 demod[k] = NULL;
880 }
881 return -EINVAL;
874} 882}
883
875EXPORT_SYMBOL(dib3000mc_attach); 884EXPORT_SYMBOL(dib3000mc_attach);
876 885
877static struct dvb_frontend_ops dib3000mc_ops = { 886static struct dvb_frontend_ops dib3000mc_ops = {
878
879 .info = { 887 .info = {
880 .name = "DiBcom 3000P/M-C DVB-T", 888 .name = "DiBcom 3000MC/P",
881 .type = FE_OFDM, 889 .type = FE_OFDM,
882 .frequency_min = 44250000, 890 .frequency_min = 44250000,
883 .frequency_max = 867250000, 891 .frequency_max = 867250000,
884 .frequency_stepsize = 62500, 892 .frequency_stepsize = 62500,
885 .caps = FE_CAN_INVERSION_AUTO | 893 .caps = FE_CAN_INVERSION_AUTO |
886 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 894 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
887 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 895 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
888 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 896 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
889 FE_CAN_TRANSMISSION_MODE_AUTO | 897 FE_CAN_TRANSMISSION_MODE_AUTO |
890 FE_CAN_GUARD_INTERVAL_AUTO | 898 FE_CAN_GUARD_INTERVAL_AUTO |
891 FE_CAN_RECOVER | 899 FE_CAN_RECOVER |
892 FE_CAN_HIERARCHY_AUTO, 900 FE_CAN_HIERARCHY_AUTO,
893 }, 901 },
894 902
895 .release = dib3000mc_release, 903 .release = dib3000mc_release,
896 904
897 .init = dib3000mc_fe_init_nonmobile, 905 .init = dib3000mc_init,
898 .sleep = dib3000mc_sleep, 906 .sleep = dib3000mc_sleep,
899 907
900 .set_frontend = dib3000mc_set_frontend_and_tuner, 908 .set_frontend = dib3000mc_set_frontend,
901 .get_frontend = dib3000mc_get_frontend, 909 .get_tune_settings = dib3000mc_fe_get_tune_settings,
902 .get_tune_settings = dib3000mc_fe_get_tune_settings, 910 .get_frontend = dib3000mc_get_frontend,
903 911
904 .read_status = dib3000mc_read_status, 912 .read_status = dib3000mc_read_status,
905 .read_ber = dib3000mc_read_ber, 913 .read_ber = dib3000mc_read_ber,
906 .read_signal_strength = dib3000mc_read_signal_strength, 914 .read_signal_strength = dib3000mc_read_signal_strength,
907 .read_snr = dib3000mc_read_snr, 915 .read_snr = dib3000mc_read_snr,
908 .read_ucblocks = dib3000mc_read_unc_blocks, 916 .read_ucblocks = dib3000mc_read_unc_blocks,
909}; 917};
910 918
911MODULE_AUTHOR(DRIVER_AUTHOR); 919MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
912MODULE_DESCRIPTION(DRIVER_DESC); 920MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
913MODULE_LICENSE("GPL"); 921MODULE_LICENSE("GPL");