diff options
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r-- | drivers/media/dvb/frontends/cx22702.c | 506 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/cx22702.h | 20 |
2 files changed, 317 insertions, 209 deletions
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 9430e03dba6c..5d1abe34bddb 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -34,13 +34,12 @@ | |||
34 | #include "dvb_frontend.h" | 34 | #include "dvb_frontend.h" |
35 | #include "cx22702.h" | 35 | #include "cx22702.h" |
36 | 36 | ||
37 | |||
38 | struct cx22702_state { | 37 | struct cx22702_state { |
39 | 38 | ||
40 | struct i2c_adapter* i2c; | 39 | struct i2c_adapter *i2c; |
41 | 40 | ||
42 | /* configuration settings */ | 41 | /* configuration settings */ |
43 | const struct cx22702_config* config; | 42 | const struct cx22702_config *config; |
44 | 43 | ||
45 | struct dvb_frontend frontend; | 44 | struct dvb_frontend frontend; |
46 | 45 | ||
@@ -49,10 +48,13 @@ struct cx22702_state { | |||
49 | }; | 48 | }; |
50 | 49 | ||
51 | static int debug; | 50 | static int debug; |
51 | module_param(debug, int, 0644); | ||
52 | MODULE_PARM_DESC(debug, "Enable verbose debug messages"); | ||
53 | |||
52 | #define dprintk if (debug) printk | 54 | #define dprintk if (debug) printk |
53 | 55 | ||
54 | /* Register values to initialise the demod */ | 56 | /* Register values to initialise the demod */ |
55 | static u8 init_tab [] = { | 57 | static u8 init_tab[] = { |
56 | 0x00, 0x00, /* Stop aquisition */ | 58 | 0x00, 0x00, /* Stop aquisition */ |
57 | 0x0B, 0x06, | 59 | 0x0B, 0x06, |
58 | 0x09, 0x01, | 60 | 0x09, 0x01, |
@@ -80,65 +82,67 @@ static u8 init_tab [] = { | |||
80 | 0xfd, 0x00, | 82 | 0xfd, 0x00, |
81 | }; | 83 | }; |
82 | 84 | ||
83 | static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data) | 85 | static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data) |
84 | { | 86 | { |
85 | int ret; | 87 | int ret; |
86 | u8 buf [] = { reg, data }; | 88 | u8 buf[] = { reg, data }; |
87 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; | 89 | struct i2c_msg msg = { |
90 | .addr = state->config->demod_address, .flags = 0, | ||
91 | .buf = buf, .len = 2 }; | ||
88 | 92 | ||
89 | ret = i2c_transfer(state->i2c, &msg, 1); | 93 | ret = i2c_transfer(state->i2c, &msg, 1); |
90 | 94 | ||
91 | if (ret != 1) | 95 | if (ret != 1) |
92 | printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", | 96 | printk(KERN_ERR |
97 | "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", | ||
93 | __func__, reg, data, ret); | 98 | __func__, reg, data, ret); |
94 | 99 | ||
95 | return (ret != 1) ? -1 : 0; | 100 | return (ret != 1) ? -1 : 0; |
96 | } | 101 | } |
97 | 102 | ||
98 | static u8 cx22702_readreg (struct cx22702_state* state, u8 reg) | 103 | static u8 cx22702_readreg(struct cx22702_state *state, u8 reg) |
99 | { | 104 | { |
100 | int ret; | 105 | int ret; |
101 | u8 b0 [] = { reg }; | 106 | u8 b0[] = { reg }; |
102 | u8 b1 [] = { 0 }; | 107 | u8 b1[] = { 0 }; |
103 | 108 | ||
104 | struct i2c_msg msg [] = { | 109 | struct i2c_msg msg[] = { |
105 | { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | 110 | { .addr = state->config->demod_address, .flags = 0, |
106 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; | 111 | .buf = b0, .len = 1 }, |
112 | { .addr = state->config->demod_address, .flags = I2C_M_RD, | ||
113 | .buf = b1, .len = 1 } }; | ||
107 | 114 | ||
108 | ret = i2c_transfer(state->i2c, msg, 2); | 115 | ret = i2c_transfer(state->i2c, msg, 2); |
109 | 116 | ||
110 | if (ret != 2) | 117 | if (ret != 2) |
111 | printk("%s: readreg error (ret == %i)\n", __func__, ret); | 118 | printk(KERN_ERR "%s: readreg error (ret == %i)\n", |
119 | __func__, ret); | ||
112 | 120 | ||
113 | return b1[0]; | 121 | return b1[0]; |
114 | } | 122 | } |
115 | 123 | ||
116 | static int cx22702_set_inversion (struct cx22702_state *state, int inversion) | 124 | static int cx22702_set_inversion(struct cx22702_state *state, int inversion) |
117 | { | 125 | { |
118 | u8 val; | 126 | u8 val; |
119 | 127 | ||
120 | switch (inversion) { | 128 | switch (inversion) { |
121 | 129 | case INVERSION_AUTO: | |
122 | case INVERSION_AUTO: | 130 | return -EOPNOTSUPP; |
123 | return -EOPNOTSUPP; | 131 | case INVERSION_ON: |
124 | 132 | val = cx22702_readreg(state, 0x0C); | |
125 | case INVERSION_ON: | 133 | return cx22702_writereg(state, 0x0C, val | 0x01); |
126 | val = cx22702_readreg (state, 0x0C); | 134 | case INVERSION_OFF: |
127 | return cx22702_writereg (state, 0x0C, val | 0x01); | 135 | val = cx22702_readreg(state, 0x0C); |
128 | 136 | return cx22702_writereg(state, 0x0C, val & 0xfe); | |
129 | case INVERSION_OFF: | 137 | default: |
130 | val = cx22702_readreg (state, 0x0C); | 138 | return -EINVAL; |
131 | return cx22702_writereg (state, 0x0C, val & 0xfe); | ||
132 | |||
133 | default: | ||
134 | return -EINVAL; | ||
135 | |||
136 | } | 139 | } |
137 | 140 | ||
138 | } | 141 | } |
139 | 142 | ||
140 | /* Retrieve the demod settings */ | 143 | /* Retrieve the demod settings */ |
141 | static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_parameters *p) | 144 | static int cx22702_get_tps(struct cx22702_state *state, |
145 | struct dvb_ofdm_parameters *p) | ||
142 | { | 146 | { |
143 | u8 val; | 147 | u8 val; |
144 | 148 | ||
@@ -146,180 +150,281 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet | |||
146 | if (!(cx22702_readreg(state, 0x0A) & 0x20)) | 150 | if (!(cx22702_readreg(state, 0x0A) & 0x20)) |
147 | return -EAGAIN; | 151 | return -EAGAIN; |
148 | 152 | ||
149 | val = cx22702_readreg (state, 0x01); | 153 | val = cx22702_readreg(state, 0x01); |
150 | switch( (val&0x18)>>3) { | 154 | switch ((val & 0x18) >> 3) { |
151 | case 0: p->constellation = QPSK; break; | 155 | case 0: |
152 | case 1: p->constellation = QAM_16; break; | 156 | p->constellation = QPSK; |
153 | case 2: p->constellation = QAM_64; break; | 157 | break; |
158 | case 1: | ||
159 | p->constellation = QAM_16; | ||
160 | break; | ||
161 | case 2: | ||
162 | p->constellation = QAM_64; | ||
163 | break; | ||
154 | } | 164 | } |
155 | switch( val&0x07 ) { | 165 | switch (val & 0x07) { |
156 | case 0: p->hierarchy_information = HIERARCHY_NONE; break; | 166 | case 0: |
157 | case 1: p->hierarchy_information = HIERARCHY_1; break; | 167 | p->hierarchy_information = HIERARCHY_NONE; |
158 | case 2: p->hierarchy_information = HIERARCHY_2; break; | 168 | break; |
159 | case 3: p->hierarchy_information = HIERARCHY_4; break; | 169 | case 1: |
170 | p->hierarchy_information = HIERARCHY_1; | ||
171 | break; | ||
172 | case 2: | ||
173 | p->hierarchy_information = HIERARCHY_2; | ||
174 | break; | ||
175 | case 3: | ||
176 | p->hierarchy_information = HIERARCHY_4; | ||
177 | break; | ||
160 | } | 178 | } |
161 | 179 | ||
162 | 180 | ||
163 | val = cx22702_readreg (state, 0x02); | 181 | val = cx22702_readreg(state, 0x02); |
164 | switch( (val&0x38)>>3 ) { | 182 | switch ((val & 0x38) >> 3) { |
165 | case 0: p->code_rate_HP = FEC_1_2; break; | 183 | case 0: |
166 | case 1: p->code_rate_HP = FEC_2_3; break; | 184 | p->code_rate_HP = FEC_1_2; |
167 | case 2: p->code_rate_HP = FEC_3_4; break; | 185 | break; |
168 | case 3: p->code_rate_HP = FEC_5_6; break; | 186 | case 1: |
169 | case 4: p->code_rate_HP = FEC_7_8; break; | 187 | p->code_rate_HP = FEC_2_3; |
188 | break; | ||
189 | case 2: | ||
190 | p->code_rate_HP = FEC_3_4; | ||
191 | break; | ||
192 | case 3: | ||
193 | p->code_rate_HP = FEC_5_6; | ||
194 | break; | ||
195 | case 4: | ||
196 | p->code_rate_HP = FEC_7_8; | ||
197 | break; | ||
170 | } | 198 | } |
171 | switch( val&0x07 ) { | 199 | switch (val & 0x07) { |
172 | case 0: p->code_rate_LP = FEC_1_2; break; | 200 | case 0: |
173 | case 1: p->code_rate_LP = FEC_2_3; break; | 201 | p->code_rate_LP = FEC_1_2; |
174 | case 2: p->code_rate_LP = FEC_3_4; break; | 202 | break; |
175 | case 3: p->code_rate_LP = FEC_5_6; break; | 203 | case 1: |
176 | case 4: p->code_rate_LP = FEC_7_8; break; | 204 | p->code_rate_LP = FEC_2_3; |
205 | break; | ||
206 | case 2: | ||
207 | p->code_rate_LP = FEC_3_4; | ||
208 | break; | ||
209 | case 3: | ||
210 | p->code_rate_LP = FEC_5_6; | ||
211 | break; | ||
212 | case 4: | ||
213 | p->code_rate_LP = FEC_7_8; | ||
214 | break; | ||
177 | } | 215 | } |
178 | 216 | ||
179 | 217 | val = cx22702_readreg(state, 0x03); | |
180 | val = cx22702_readreg (state, 0x03); | 218 | switch ((val & 0x0c) >> 2) { |
181 | switch( (val&0x0c)>>2 ) { | 219 | case 0: |
182 | case 0: p->guard_interval = GUARD_INTERVAL_1_32; break; | 220 | p->guard_interval = GUARD_INTERVAL_1_32; |
183 | case 1: p->guard_interval = GUARD_INTERVAL_1_16; break; | 221 | break; |
184 | case 2: p->guard_interval = GUARD_INTERVAL_1_8; break; | 222 | case 1: |
185 | case 3: p->guard_interval = GUARD_INTERVAL_1_4; break; | 223 | p->guard_interval = GUARD_INTERVAL_1_16; |
224 | break; | ||
225 | case 2: | ||
226 | p->guard_interval = GUARD_INTERVAL_1_8; | ||
227 | break; | ||
228 | case 3: | ||
229 | p->guard_interval = GUARD_INTERVAL_1_4; | ||
230 | break; | ||
186 | } | 231 | } |
187 | switch( val&0x03 ) { | 232 | switch (val & 0x03) { |
188 | case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break; | 233 | case 0: |
189 | case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break; | 234 | p->transmission_mode = TRANSMISSION_MODE_2K; |
235 | break; | ||
236 | case 1: | ||
237 | p->transmission_mode = TRANSMISSION_MODE_8K; | ||
238 | break; | ||
190 | } | 239 | } |
191 | 240 | ||
192 | return 0; | 241 | return 0; |
193 | } | 242 | } |
194 | 243 | ||
195 | static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | 244 | static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
196 | { | 245 | { |
197 | struct cx22702_state* state = fe->demodulator_priv; | 246 | struct cx22702_state *state = fe->demodulator_priv; |
198 | dprintk ("%s(%d)\n", __func__, enable); | 247 | dprintk("%s(%d)\n", __func__, enable); |
199 | if (enable) | 248 | if (enable) |
200 | return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe); | 249 | return cx22702_writereg(state, 0x0D, |
250 | cx22702_readreg(state, 0x0D) & 0xfe); | ||
201 | else | 251 | else |
202 | return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1); | 252 | return cx22702_writereg(state, 0x0D, |
253 | cx22702_readreg(state, 0x0D) | 1); | ||
203 | } | 254 | } |
204 | 255 | ||
205 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ | 256 | /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ |
206 | static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 257 | static int cx22702_set_tps(struct dvb_frontend *fe, |
258 | struct dvb_frontend_parameters *p) | ||
207 | { | 259 | { |
208 | u8 val; | 260 | u8 val; |
209 | struct cx22702_state* state = fe->demodulator_priv; | 261 | struct cx22702_state *state = fe->demodulator_priv; |
210 | 262 | ||
211 | if (fe->ops.tuner_ops.set_params) { | 263 | if (fe->ops.tuner_ops.set_params) { |
212 | fe->ops.tuner_ops.set_params(fe, p); | 264 | fe->ops.tuner_ops.set_params(fe, p); |
213 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | 265 | if (fe->ops.i2c_gate_ctrl) |
266 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
214 | } | 267 | } |
215 | 268 | ||
216 | /* set inversion */ | 269 | /* set inversion */ |
217 | cx22702_set_inversion (state, p->inversion); | 270 | cx22702_set_inversion(state, p->inversion); |
218 | 271 | ||
219 | /* set bandwidth */ | 272 | /* set bandwidth */ |
220 | switch(p->u.ofdm.bandwidth) { | 273 | switch (p->u.ofdm.bandwidth) { |
221 | case BANDWIDTH_6_MHZ: | 274 | case BANDWIDTH_6_MHZ: |
222 | cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20 ); | 275 | cx22702_writereg(state, 0x0C, |
276 | (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20); | ||
223 | break; | 277 | break; |
224 | case BANDWIDTH_7_MHZ: | 278 | case BANDWIDTH_7_MHZ: |
225 | cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10 ); | 279 | cx22702_writereg(state, 0x0C, |
280 | (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10); | ||
226 | break; | 281 | break; |
227 | case BANDWIDTH_8_MHZ: | 282 | case BANDWIDTH_8_MHZ: |
228 | cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf ); | 283 | cx22702_writereg(state, 0x0C, |
284 | cx22702_readreg(state, 0x0C) & 0xcf); | ||
229 | break; | 285 | break; |
230 | default: | 286 | default: |
231 | dprintk ("%s: invalid bandwidth\n",__func__); | 287 | dprintk("%s: invalid bandwidth\n", __func__); |
232 | return -EINVAL; | 288 | return -EINVAL; |
233 | } | 289 | } |
234 | 290 | ||
235 | 291 | p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */ | |
236 | p->u.ofdm.code_rate_LP = FEC_AUTO; //temp hack as manual not working | ||
237 | 292 | ||
238 | /* use auto configuration? */ | 293 | /* use auto configuration? */ |
239 | if((p->u.ofdm.hierarchy_information==HIERARCHY_AUTO) || | 294 | if ((p->u.ofdm.hierarchy_information == HIERARCHY_AUTO) || |
240 | (p->u.ofdm.constellation==QAM_AUTO) || | 295 | (p->u.ofdm.constellation == QAM_AUTO) || |
241 | (p->u.ofdm.code_rate_HP==FEC_AUTO) || | 296 | (p->u.ofdm.code_rate_HP == FEC_AUTO) || |
242 | (p->u.ofdm.code_rate_LP==FEC_AUTO) || | 297 | (p->u.ofdm.code_rate_LP == FEC_AUTO) || |
243 | (p->u.ofdm.guard_interval==GUARD_INTERVAL_AUTO) || | 298 | (p->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO) || |
244 | (p->u.ofdm.transmission_mode==TRANSMISSION_MODE_AUTO) ) { | 299 | (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO)) { |
245 | 300 | ||
246 | /* TPS Source - use hardware driven values */ | 301 | /* TPS Source - use hardware driven values */ |
247 | cx22702_writereg(state, 0x06, 0x10); | 302 | cx22702_writereg(state, 0x06, 0x10); |
248 | cx22702_writereg(state, 0x07, 0x9); | 303 | cx22702_writereg(state, 0x07, 0x9); |
249 | cx22702_writereg(state, 0x08, 0xC1); | 304 | cx22702_writereg(state, 0x08, 0xC1); |
250 | cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc ); | 305 | cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) |
251 | cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); | 306 | & 0xfc); |
307 | cx22702_writereg(state, 0x0C, | ||
308 | (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); | ||
252 | cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ | 309 | cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ |
253 | dprintk("%s: Autodetecting\n",__func__); | 310 | dprintk("%s: Autodetecting\n", __func__); |
254 | return 0; | 311 | return 0; |
255 | } | 312 | } |
256 | 313 | ||
257 | /* manually programmed values */ | 314 | /* manually programmed values */ |
258 | val=0; | 315 | val = 0; |
259 | switch(p->u.ofdm.constellation) { | 316 | switch (p->u.ofdm.constellation) { |
260 | case QPSK: val = (val&0xe7); break; | 317 | case QPSK: |
261 | case QAM_16: val = (val&0xe7)|0x08; break; | 318 | val = (val & 0xe7); |
262 | case QAM_64: val = (val&0xe7)|0x10; break; | 319 | break; |
263 | default: | 320 | case QAM_16: |
264 | dprintk ("%s: invalid constellation\n",__func__); | 321 | val = (val & 0xe7) | 0x08; |
265 | return -EINVAL; | 322 | break; |
323 | case QAM_64: | ||
324 | val = (val & 0xe7) | 0x10; | ||
325 | break; | ||
326 | default: | ||
327 | dprintk("%s: invalid constellation\n", __func__); | ||
328 | return -EINVAL; | ||
266 | } | 329 | } |
267 | switch(p->u.ofdm.hierarchy_information) { | 330 | switch (p->u.ofdm.hierarchy_information) { |
268 | case HIERARCHY_NONE: val = (val&0xf8); break; | 331 | case HIERARCHY_NONE: |
269 | case HIERARCHY_1: val = (val&0xf8)|1; break; | 332 | val = (val & 0xf8); |
270 | case HIERARCHY_2: val = (val&0xf8)|2; break; | 333 | break; |
271 | case HIERARCHY_4: val = (val&0xf8)|3; break; | 334 | case HIERARCHY_1: |
272 | default: | 335 | val = (val & 0xf8) | 1; |
273 | dprintk ("%s: invalid hierarchy\n",__func__); | 336 | break; |
274 | return -EINVAL; | 337 | case HIERARCHY_2: |
338 | val = (val & 0xf8) | 2; | ||
339 | break; | ||
340 | case HIERARCHY_4: | ||
341 | val = (val & 0xf8) | 3; | ||
342 | break; | ||
343 | default: | ||
344 | dprintk("%s: invalid hierarchy\n", __func__); | ||
345 | return -EINVAL; | ||
275 | } | 346 | } |
276 | cx22702_writereg (state, 0x06, val); | 347 | cx22702_writereg(state, 0x06, val); |
277 | 348 | ||
278 | val=0; | 349 | val = 0; |
279 | switch(p->u.ofdm.code_rate_HP) { | 350 | switch (p->u.ofdm.code_rate_HP) { |
280 | case FEC_NONE: | 351 | case FEC_NONE: |
281 | case FEC_1_2: val = (val&0xc7); break; | 352 | case FEC_1_2: |
282 | case FEC_2_3: val = (val&0xc7)|0x08; break; | 353 | val = (val & 0xc7); |
283 | case FEC_3_4: val = (val&0xc7)|0x10; break; | 354 | break; |
284 | case FEC_5_6: val = (val&0xc7)|0x18; break; | 355 | case FEC_2_3: |
285 | case FEC_7_8: val = (val&0xc7)|0x20; break; | 356 | val = (val & 0xc7) | 0x08; |
286 | default: | 357 | break; |
287 | dprintk ("%s: invalid code_rate_HP\n",__func__); | 358 | case FEC_3_4: |
288 | return -EINVAL; | 359 | val = (val & 0xc7) | 0x10; |
360 | break; | ||
361 | case FEC_5_6: | ||
362 | val = (val & 0xc7) | 0x18; | ||
363 | break; | ||
364 | case FEC_7_8: | ||
365 | val = (val & 0xc7) | 0x20; | ||
366 | break; | ||
367 | default: | ||
368 | dprintk("%s: invalid code_rate_HP\n", __func__); | ||
369 | return -EINVAL; | ||
289 | } | 370 | } |
290 | switch(p->u.ofdm.code_rate_LP) { | 371 | switch (p->u.ofdm.code_rate_LP) { |
291 | case FEC_NONE: | 372 | case FEC_NONE: |
292 | case FEC_1_2: val = (val&0xf8); break; | 373 | case FEC_1_2: |
293 | case FEC_2_3: val = (val&0xf8)|1; break; | 374 | val = (val & 0xf8); |
294 | case FEC_3_4: val = (val&0xf8)|2; break; | 375 | break; |
295 | case FEC_5_6: val = (val&0xf8)|3; break; | 376 | case FEC_2_3: |
296 | case FEC_7_8: val = (val&0xf8)|4; break; | 377 | val = (val & 0xf8) | 1; |
297 | default: | 378 | break; |
298 | dprintk ("%s: invalid code_rate_LP\n",__func__); | 379 | case FEC_3_4: |
299 | return -EINVAL; | 380 | val = (val & 0xf8) | 2; |
381 | break; | ||
382 | case FEC_5_6: | ||
383 | val = (val & 0xf8) | 3; | ||
384 | break; | ||
385 | case FEC_7_8: | ||
386 | val = (val & 0xf8) | 4; | ||
387 | break; | ||
388 | default: | ||
389 | dprintk("%s: invalid code_rate_LP\n", __func__); | ||
390 | return -EINVAL; | ||
300 | } | 391 | } |
301 | cx22702_writereg (state, 0x07, val); | 392 | cx22702_writereg(state, 0x07, val); |
302 | 393 | ||
303 | val=0; | 394 | val = 0; |
304 | switch(p->u.ofdm.guard_interval) { | 395 | switch (p->u.ofdm.guard_interval) { |
305 | case GUARD_INTERVAL_1_32: val = (val&0xf3); break; | 396 | case GUARD_INTERVAL_1_32: |
306 | case GUARD_INTERVAL_1_16: val = (val&0xf3)|0x04; break; | 397 | val = (val & 0xf3); |
307 | case GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break; | 398 | break; |
308 | case GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break; | 399 | case GUARD_INTERVAL_1_16: |
309 | default: | 400 | val = (val & 0xf3) | 0x04; |
310 | dprintk ("%s: invalid guard_interval\n",__func__); | 401 | break; |
311 | return -EINVAL; | 402 | case GUARD_INTERVAL_1_8: |
403 | val = (val & 0xf3) | 0x08; | ||
404 | break; | ||
405 | case GUARD_INTERVAL_1_4: | ||
406 | val = (val & 0xf3) | 0x0c; | ||
407 | break; | ||
408 | default: | ||
409 | dprintk("%s: invalid guard_interval\n", __func__); | ||
410 | return -EINVAL; | ||
312 | } | 411 | } |
313 | switch(p->u.ofdm.transmission_mode) { | 412 | switch (p->u.ofdm.transmission_mode) { |
314 | case TRANSMISSION_MODE_2K: val = (val&0xfc); break; | 413 | case TRANSMISSION_MODE_2K: |
315 | case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break; | 414 | val = (val & 0xfc); |
316 | default: | 415 | break; |
317 | dprintk ("%s: invalid transmission_mode\n",__func__); | 416 | case TRANSMISSION_MODE_8K: |
318 | return -EINVAL; | 417 | val = (val & 0xfc) | 1; |
418 | break; | ||
419 | default: | ||
420 | dprintk("%s: invalid transmission_mode\n", __func__); | ||
421 | return -EINVAL; | ||
319 | } | 422 | } |
320 | cx22702_writereg(state, 0x08, val); | 423 | cx22702_writereg(state, 0x08, val); |
321 | cx22702_writereg(state, 0x0B, (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02 ); | 424 | cx22702_writereg(state, 0x0B, |
322 | cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 ); | 425 | (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02); |
426 | cx22702_writereg(state, 0x0C, | ||
427 | (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); | ||
323 | 428 | ||
324 | /* Begin channel aquisition */ | 429 | /* Begin channel aquisition */ |
325 | cx22702_writereg(state, 0x00, 0x01); | 430 | cx22702_writereg(state, 0x00, 0x01); |
@@ -329,109 +434,111 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
329 | 434 | ||
330 | /* Reset the demod hardware and reset all of the configuration registers | 435 | /* Reset the demod hardware and reset all of the configuration registers |
331 | to a default state. */ | 436 | to a default state. */ |
332 | static int cx22702_init (struct dvb_frontend* fe) | 437 | static int cx22702_init(struct dvb_frontend *fe) |
333 | { | 438 | { |
334 | int i; | 439 | int i; |
335 | struct cx22702_state* state = fe->demodulator_priv; | 440 | struct cx22702_state *state = fe->demodulator_priv; |
336 | 441 | ||
337 | cx22702_writereg (state, 0x00, 0x02); | 442 | cx22702_writereg(state, 0x00, 0x02); |
338 | 443 | ||
339 | msleep(10); | 444 | msleep(10); |
340 | 445 | ||
341 | for (i=0; i<sizeof(init_tab); i+=2) | 446 | for (i = 0; i < ARRAY_SIZE(init_tab); i += 2) |
342 | cx22702_writereg (state, init_tab[i], init_tab[i+1]); | 447 | cx22702_writereg(state, init_tab[i], init_tab[i + 1]); |
343 | 448 | ||
344 | cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); | 449 | cx22702_writereg(state, 0xf8, (state->config->output_mode << 1) |
450 | & 0x02); | ||
345 | 451 | ||
346 | cx22702_i2c_gate_ctrl(fe, 0); | 452 | cx22702_i2c_gate_ctrl(fe, 0); |
347 | 453 | ||
348 | return 0; | 454 | return 0; |
349 | } | 455 | } |
350 | 456 | ||
351 | static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status) | 457 | static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status) |
352 | { | 458 | { |
353 | struct cx22702_state* state = fe->demodulator_priv; | 459 | struct cx22702_state *state = fe->demodulator_priv; |
354 | u8 reg0A; | 460 | u8 reg0A; |
355 | u8 reg23; | 461 | u8 reg23; |
356 | 462 | ||
357 | *status = 0; | 463 | *status = 0; |
358 | 464 | ||
359 | reg0A = cx22702_readreg (state, 0x0A); | 465 | reg0A = cx22702_readreg(state, 0x0A); |
360 | reg23 = cx22702_readreg (state, 0x23); | 466 | reg23 = cx22702_readreg(state, 0x23); |
361 | 467 | ||
362 | dprintk ("%s: status demod=0x%02x agc=0x%02x\n" | 468 | dprintk("%s: status demod=0x%02x agc=0x%02x\n" |
363 | ,__func__,reg0A,reg23); | 469 | , __func__, reg0A, reg23); |
364 | 470 | ||
365 | if(reg0A & 0x10) { | 471 | if (reg0A & 0x10) { |
366 | *status |= FE_HAS_LOCK; | 472 | *status |= FE_HAS_LOCK; |
367 | *status |= FE_HAS_VITERBI; | 473 | *status |= FE_HAS_VITERBI; |
368 | *status |= FE_HAS_SYNC; | 474 | *status |= FE_HAS_SYNC; |
369 | } | 475 | } |
370 | 476 | ||
371 | if(reg0A & 0x20) | 477 | if (reg0A & 0x20) |
372 | *status |= FE_HAS_CARRIER; | 478 | *status |= FE_HAS_CARRIER; |
373 | 479 | ||
374 | if(reg23 < 0xf0) | 480 | if (reg23 < 0xf0) |
375 | *status |= FE_HAS_SIGNAL; | 481 | *status |= FE_HAS_SIGNAL; |
376 | 482 | ||
377 | return 0; | 483 | return 0; |
378 | } | 484 | } |
379 | 485 | ||
380 | static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber) | 486 | static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber) |
381 | { | 487 | { |
382 | struct cx22702_state* state = fe->demodulator_priv; | 488 | struct cx22702_state *state = fe->demodulator_priv; |
383 | 489 | ||
384 | if(cx22702_readreg (state, 0xE4) & 0x02) { | 490 | if (cx22702_readreg(state, 0xE4) & 0x02) { |
385 | /* Realtime statistics */ | 491 | /* Realtime statistics */ |
386 | *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7 | 492 | *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 |
387 | | (cx22702_readreg (state, 0xDF)&0x7F); | 493 | | (cx22702_readreg(state, 0xDF) & 0x7F); |
388 | } else { | 494 | } else { |
389 | /* Averagtine statistics */ | 495 | /* Averagtine statistics */ |
390 | *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7 | 496 | *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 |
391 | | cx22702_readreg (state, 0xDF); | 497 | | cx22702_readreg(state, 0xDF); |
392 | } | 498 | } |
393 | 499 | ||
394 | return 0; | 500 | return 0; |
395 | } | 501 | } |
396 | 502 | ||
397 | static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | 503 | static int cx22702_read_signal_strength(struct dvb_frontend *fe, |
504 | u16 *signal_strength) | ||
398 | { | 505 | { |
399 | struct cx22702_state* state = fe->demodulator_priv; | 506 | struct cx22702_state *state = fe->demodulator_priv; |
400 | 507 | ||
401 | u16 rs_ber = 0; | 508 | u16 rs_ber = 0; |
402 | rs_ber = cx22702_readreg (state, 0x23); | 509 | rs_ber = cx22702_readreg(state, 0x23); |
403 | *signal_strength = (rs_ber << 8) | rs_ber; | 510 | *signal_strength = (rs_ber << 8) | rs_ber; |
404 | 511 | ||
405 | return 0; | 512 | return 0; |
406 | } | 513 | } |
407 | 514 | ||
408 | static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr) | 515 | static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr) |
409 | { | 516 | { |
410 | struct cx22702_state* state = fe->demodulator_priv; | 517 | struct cx22702_state *state = fe->demodulator_priv; |
411 | 518 | ||
412 | u16 rs_ber=0; | 519 | u16 rs_ber = 0; |
413 | if(cx22702_readreg (state, 0xE4) & 0x02) { | 520 | if (cx22702_readreg(state, 0xE4) & 0x02) { |
414 | /* Realtime statistics */ | 521 | /* Realtime statistics */ |
415 | rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7 | 522 | rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 |
416 | | (cx22702_readreg (state, 0xDF)& 0x7F); | 523 | | (cx22702_readreg(state, 0xDF) & 0x7F); |
417 | } else { | 524 | } else { |
418 | /* Averagine statistics */ | 525 | /* Averagine statistics */ |
419 | rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 8 | 526 | rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8 |
420 | | cx22702_readreg (state, 0xDF); | 527 | | cx22702_readreg(state, 0xDF); |
421 | } | 528 | } |
422 | *snr = ~rs_ber; | 529 | *snr = ~rs_ber; |
423 | 530 | ||
424 | return 0; | 531 | return 0; |
425 | } | 532 | } |
426 | 533 | ||
427 | static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 534 | static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
428 | { | 535 | { |
429 | struct cx22702_state* state = fe->demodulator_priv; | 536 | struct cx22702_state *state = fe->demodulator_priv; |
430 | 537 | ||
431 | u8 _ucblocks; | 538 | u8 _ucblocks; |
432 | 539 | ||
433 | /* RS Uncorrectable Packet Count then reset */ | 540 | /* RS Uncorrectable Packet Count then reset */ |
434 | _ucblocks = cx22702_readreg (state, 0xE3); | 541 | _ucblocks = cx22702_readreg(state, 0xE3); |
435 | if (state->prevUCBlocks < _ucblocks) | 542 | if (state->prevUCBlocks < _ucblocks) |
436 | *ucblocks = (_ucblocks - state->prevUCBlocks); | 543 | *ucblocks = (_ucblocks - state->prevUCBlocks); |
437 | else | 544 | else |
@@ -441,34 +548,36 @@ static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
441 | return 0; | 548 | return 0; |
442 | } | 549 | } |
443 | 550 | ||
444 | static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 551 | static int cx22702_get_frontend(struct dvb_frontend *fe, |
552 | struct dvb_frontend_parameters *p) | ||
445 | { | 553 | { |
446 | struct cx22702_state* state = fe->demodulator_priv; | 554 | struct cx22702_state *state = fe->demodulator_priv; |
447 | 555 | ||
448 | u8 reg0C = cx22702_readreg (state, 0x0C); | 556 | u8 reg0C = cx22702_readreg(state, 0x0C); |
449 | 557 | ||
450 | p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; | 558 | p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; |
451 | return cx22702_get_tps (state, &p->u.ofdm); | 559 | return cx22702_get_tps(state, &p->u.ofdm); |
452 | } | 560 | } |
453 | 561 | ||
454 | static int cx22702_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) | 562 | static int cx22702_get_tune_settings(struct dvb_frontend *fe, |
563 | struct dvb_frontend_tune_settings *tune) | ||
455 | { | 564 | { |
456 | tune->min_delay_ms = 1000; | 565 | tune->min_delay_ms = 1000; |
457 | return 0; | 566 | return 0; |
458 | } | 567 | } |
459 | 568 | ||
460 | static void cx22702_release(struct dvb_frontend* fe) | 569 | static void cx22702_release(struct dvb_frontend *fe) |
461 | { | 570 | { |
462 | struct cx22702_state* state = fe->demodulator_priv; | 571 | struct cx22702_state *state = fe->demodulator_priv; |
463 | kfree(state); | 572 | kfree(state); |
464 | } | 573 | } |
465 | 574 | ||
466 | static struct dvb_frontend_ops cx22702_ops; | 575 | static struct dvb_frontend_ops cx22702_ops; |
467 | 576 | ||
468 | struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | 577 | struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, |
469 | struct i2c_adapter* i2c) | 578 | struct i2c_adapter *i2c) |
470 | { | 579 | { |
471 | struct cx22702_state* state = NULL; | 580 | struct cx22702_state *state = NULL; |
472 | 581 | ||
473 | /* allocate memory for the internal state */ | 582 | /* allocate memory for the internal state */ |
474 | state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); | 583 | state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); |
@@ -485,7 +594,8 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | |||
485 | goto error; | 594 | goto error; |
486 | 595 | ||
487 | /* create dvb_frontend */ | 596 | /* create dvb_frontend */ |
488 | memcpy(&state->frontend.ops, &cx22702_ops, sizeof(struct dvb_frontend_ops)); | 597 | memcpy(&state->frontend.ops, &cx22702_ops, |
598 | sizeof(struct dvb_frontend_ops)); | ||
489 | state->frontend.demodulator_priv = state; | 599 | state->frontend.demodulator_priv = state; |
490 | return &state->frontend; | 600 | return &state->frontend; |
491 | 601 | ||
@@ -493,6 +603,7 @@ error: | |||
493 | kfree(state); | 603 | kfree(state); |
494 | return NULL; | 604 | return NULL; |
495 | } | 605 | } |
606 | EXPORT_SYMBOL(cx22702_attach); | ||
496 | 607 | ||
497 | static struct dvb_frontend_ops cx22702_ops = { | 608 | static struct dvb_frontend_ops cx22702_ops = { |
498 | 609 | ||
@@ -525,11 +636,6 @@ static struct dvb_frontend_ops cx22702_ops = { | |||
525 | .read_ucblocks = cx22702_read_ucblocks, | 636 | .read_ucblocks = cx22702_read_ucblocks, |
526 | }; | 637 | }; |
527 | 638 | ||
528 | module_param(debug, int, 0644); | ||
529 | MODULE_PARM_DESC(debug, "Enable verbose debug messages"); | ||
530 | |||
531 | MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver"); | 639 | MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver"); |
532 | MODULE_AUTHOR("Steven Toth"); | 640 | MODULE_AUTHOR("Steven Toth"); |
533 | MODULE_LICENSE("GPL"); | 641 | MODULE_LICENSE("GPL"); |
534 | |||
535 | EXPORT_SYMBOL(cx22702_attach); | ||
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h index b1e465c6c2ce..f154e1f428eb 100644 --- a/drivers/media/dvb/frontends/cx22702.h +++ b/drivers/media/dvb/frontends/cx22702.h | |||
@@ -30,8 +30,7 @@ | |||
30 | 30 | ||
31 | #include <linux/dvb/frontend.h> | 31 | #include <linux/dvb/frontend.h> |
32 | 32 | ||
33 | struct cx22702_config | 33 | struct cx22702_config { |
34 | { | ||
35 | /* the demodulator's i2c address */ | 34 | /* the demodulator's i2c address */ |
36 | u8 demod_address; | 35 | u8 demod_address; |
37 | 36 | ||
@@ -41,16 +40,19 @@ struct cx22702_config | |||
41 | u8 output_mode; | 40 | u8 output_mode; |
42 | }; | 41 | }; |
43 | 42 | ||
44 | #if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) && defined(MODULE)) | 43 | #if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \ |
45 | extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | 44 | && defined(MODULE)) |
46 | struct i2c_adapter* i2c); | 45 | extern struct dvb_frontend *cx22702_attach( |
46 | const struct cx22702_config *config, | ||
47 | struct i2c_adapter *i2c); | ||
47 | #else | 48 | #else |
48 | static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | 49 | static inline struct dvb_frontend *cx22702_attach( |
49 | struct i2c_adapter* i2c) | 50 | const struct cx22702_config *config, |
51 | struct i2c_adapter *i2c) | ||
50 | { | 52 | { |
51 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 53 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
52 | return NULL; | 54 | return NULL; |
53 | } | 55 | } |
54 | #endif // CONFIG_DVB_CX22702 | 56 | #endif |
55 | 57 | ||
56 | #endif // CX22702_H | 58 | #endif |