Commit c5dc3b98fffaf183bb3d5bf690bfab9f6705c5e1

Authored by Antti Palosaari
Committed by Mauro Carvalho Chehab
1 parent 4562620159

[media] fc0012: remove unused callback and correct one comment

There is no need to keep dummy sleep() callback implementation as
DVB-core checks existence of it before calls callback. Due to that
we can remove it.
FC0012 is based of direct-conversion receiver architecture
(aka Zero-IF) where is no IF used. Due to that IF is always 0 Hz.
Fix comment to point that.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Acked-by: Hans-Frieder Vogt <hfvogt@gmx.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 1 changed file with 1 additions and 9 deletions Inline Diff

drivers/media/tuners/fc0012.c
1 /* 1 /*
2 * Fitipower FC0012 tuner driver 2 * Fitipower FC0012 tuner driver
3 * 3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net> 4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */ 19 */
20 20
21 #include "fc0012.h" 21 #include "fc0012.h"
22 #include "fc0012-priv.h" 22 #include "fc0012-priv.h"
23 23
24 static int fc0012_writereg(struct fc0012_priv *priv, u8 reg, u8 val) 24 static int fc0012_writereg(struct fc0012_priv *priv, u8 reg, u8 val)
25 { 25 {
26 u8 buf[2] = {reg, val}; 26 u8 buf[2] = {reg, val};
27 struct i2c_msg msg = { 27 struct i2c_msg msg = {
28 .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2 28 .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
29 }; 29 };
30 30
31 if (i2c_transfer(priv->i2c, &msg, 1) != 1) { 31 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
32 dev_err(&priv->i2c->dev, 32 dev_err(&priv->i2c->dev,
33 "%s: I2C write reg failed, reg: %02x, val: %02x\n", 33 "%s: I2C write reg failed, reg: %02x, val: %02x\n",
34 KBUILD_MODNAME, reg, val); 34 KBUILD_MODNAME, reg, val);
35 return -EREMOTEIO; 35 return -EREMOTEIO;
36 } 36 }
37 return 0; 37 return 0;
38 } 38 }
39 39
40 static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val) 40 static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val)
41 { 41 {
42 struct i2c_msg msg[2] = { 42 struct i2c_msg msg[2] = {
43 { .addr = priv->cfg->i2c_address, .flags = 0, 43 { .addr = priv->cfg->i2c_address, .flags = 0,
44 .buf = &reg, .len = 1 }, 44 .buf = &reg, .len = 1 },
45 { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, 45 { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
46 .buf = val, .len = 1 }, 46 .buf = val, .len = 1 },
47 }; 47 };
48 48
49 if (i2c_transfer(priv->i2c, msg, 2) != 2) { 49 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
50 dev_err(&priv->i2c->dev, 50 dev_err(&priv->i2c->dev,
51 "%s: I2C read reg failed, reg: %02x\n", 51 "%s: I2C read reg failed, reg: %02x\n",
52 KBUILD_MODNAME, reg); 52 KBUILD_MODNAME, reg);
53 return -EREMOTEIO; 53 return -EREMOTEIO;
54 } 54 }
55 return 0; 55 return 0;
56 } 56 }
57 57
58 static int fc0012_release(struct dvb_frontend *fe) 58 static int fc0012_release(struct dvb_frontend *fe)
59 { 59 {
60 kfree(fe->tuner_priv); 60 kfree(fe->tuner_priv);
61 fe->tuner_priv = NULL; 61 fe->tuner_priv = NULL;
62 return 0; 62 return 0;
63 } 63 }
64 64
65 static int fc0012_init(struct dvb_frontend *fe) 65 static int fc0012_init(struct dvb_frontend *fe)
66 { 66 {
67 struct fc0012_priv *priv = fe->tuner_priv; 67 struct fc0012_priv *priv = fe->tuner_priv;
68 int i, ret = 0; 68 int i, ret = 0;
69 unsigned char reg[] = { 69 unsigned char reg[] = {
70 0x00, /* dummy reg. 0 */ 70 0x00, /* dummy reg. 0 */
71 0x05, /* reg. 0x01 */ 71 0x05, /* reg. 0x01 */
72 0x10, /* reg. 0x02 */ 72 0x10, /* reg. 0x02 */
73 0x00, /* reg. 0x03 */ 73 0x00, /* reg. 0x03 */
74 0x00, /* reg. 0x04 */ 74 0x00, /* reg. 0x04 */
75 0x0f, /* reg. 0x05: may also be 0x0a */ 75 0x0f, /* reg. 0x05: may also be 0x0a */
76 0x00, /* reg. 0x06: divider 2, VCO slow */ 76 0x00, /* reg. 0x06: divider 2, VCO slow */
77 0x00, /* reg. 0x07: may also be 0x0f */ 77 0x00, /* reg. 0x07: may also be 0x0f */
78 0xff, /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256, 78 0xff, /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
79 Loop Bw 1/8 */ 79 Loop Bw 1/8 */
80 0x6e, /* reg. 0x09: Disable LoopThrough, Enable LoopThrough: 0x6f */ 80 0x6e, /* reg. 0x09: Disable LoopThrough, Enable LoopThrough: 0x6f */
81 0xb8, /* reg. 0x0a: Disable LO Test Buffer */ 81 0xb8, /* reg. 0x0a: Disable LO Test Buffer */
82 0x82, /* reg. 0x0b: Output Clock is same as clock frequency, 82 0x82, /* reg. 0x0b: Output Clock is same as clock frequency,
83 may also be 0x83 */ 83 may also be 0x83 */
84 0xfc, /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */ 84 0xfc, /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
85 0x02, /* reg. 0x0d: AGC Not Forcing & LNA Forcing, 0x02 for DVB-T */ 85 0x02, /* reg. 0x0d: AGC Not Forcing & LNA Forcing, 0x02 for DVB-T */
86 0x00, /* reg. 0x0e */ 86 0x00, /* reg. 0x0e */
87 0x00, /* reg. 0x0f */ 87 0x00, /* reg. 0x0f */
88 0x00, /* reg. 0x10: may also be 0x0d */ 88 0x00, /* reg. 0x10: may also be 0x0d */
89 0x00, /* reg. 0x11 */ 89 0x00, /* reg. 0x11 */
90 0x1f, /* reg. 0x12: Set to maximum gain */ 90 0x1f, /* reg. 0x12: Set to maximum gain */
91 0x08, /* reg. 0x13: Set to Middle Gain: 0x08, 91 0x08, /* reg. 0x13: Set to Middle Gain: 0x08,
92 Low Gain: 0x00, High Gain: 0x10, enable IX2: 0x80 */ 92 Low Gain: 0x00, High Gain: 0x10, enable IX2: 0x80 */
93 0x00, /* reg. 0x14 */ 93 0x00, /* reg. 0x14 */
94 0x04, /* reg. 0x15: Enable LNA COMPS */ 94 0x04, /* reg. 0x15: Enable LNA COMPS */
95 }; 95 };
96 96
97 switch (priv->cfg->xtal_freq) { 97 switch (priv->cfg->xtal_freq) {
98 case FC_XTAL_27_MHZ: 98 case FC_XTAL_27_MHZ:
99 case FC_XTAL_28_8_MHZ: 99 case FC_XTAL_28_8_MHZ:
100 reg[0x07] |= 0x20; 100 reg[0x07] |= 0x20;
101 break; 101 break;
102 case FC_XTAL_36_MHZ: 102 case FC_XTAL_36_MHZ:
103 default: 103 default:
104 break; 104 break;
105 } 105 }
106 106
107 if (priv->cfg->dual_master) 107 if (priv->cfg->dual_master)
108 reg[0x0c] |= 0x02; 108 reg[0x0c] |= 0x02;
109 109
110 if (priv->cfg->loop_through) 110 if (priv->cfg->loop_through)
111 reg[0x09] |= 0x01; 111 reg[0x09] |= 0x01;
112 112
113 if (fe->ops.i2c_gate_ctrl) 113 if (fe->ops.i2c_gate_ctrl)
114 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ 114 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
115 115
116 for (i = 1; i < sizeof(reg); i++) { 116 for (i = 1; i < sizeof(reg); i++) {
117 ret = fc0012_writereg(priv, i, reg[i]); 117 ret = fc0012_writereg(priv, i, reg[i]);
118 if (ret) 118 if (ret)
119 break; 119 break;
120 } 120 }
121 121
122 if (fe->ops.i2c_gate_ctrl) 122 if (fe->ops.i2c_gate_ctrl)
123 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ 123 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
124 124
125 if (ret) 125 if (ret)
126 dev_err(&priv->i2c->dev, "%s: fc0012_writereg failed: %d\n", 126 dev_err(&priv->i2c->dev, "%s: fc0012_writereg failed: %d\n",
127 KBUILD_MODNAME, ret); 127 KBUILD_MODNAME, ret);
128 128
129 return ret; 129 return ret;
130 } 130 }
131 131
132 static int fc0012_sleep(struct dvb_frontend *fe)
133 {
134 /* nothing to do here */
135 return 0;
136 }
137
138 static int fc0012_set_params(struct dvb_frontend *fe) 132 static int fc0012_set_params(struct dvb_frontend *fe)
139 { 133 {
140 struct fc0012_priv *priv = fe->tuner_priv; 134 struct fc0012_priv *priv = fe->tuner_priv;
141 int i, ret = 0; 135 int i, ret = 0;
142 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 136 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
143 u32 freq = p->frequency / 1000; 137 u32 freq = p->frequency / 1000;
144 u32 delsys = p->delivery_system; 138 u32 delsys = p->delivery_system;
145 unsigned char reg[7], am, pm, multi, tmp; 139 unsigned char reg[7], am, pm, multi, tmp;
146 unsigned long f_vco; 140 unsigned long f_vco;
147 unsigned short xtal_freq_khz_2, xin, xdiv; 141 unsigned short xtal_freq_khz_2, xin, xdiv;
148 int vco_select = false; 142 int vco_select = false;
149 143
150 if (fe->callback) { 144 if (fe->callback) {
151 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER, 145 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
152 FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1)); 146 FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
153 if (ret) 147 if (ret)
154 goto exit; 148 goto exit;
155 } 149 }
156 150
157 switch (priv->cfg->xtal_freq) { 151 switch (priv->cfg->xtal_freq) {
158 case FC_XTAL_27_MHZ: 152 case FC_XTAL_27_MHZ:
159 xtal_freq_khz_2 = 27000 / 2; 153 xtal_freq_khz_2 = 27000 / 2;
160 break; 154 break;
161 case FC_XTAL_36_MHZ: 155 case FC_XTAL_36_MHZ:
162 xtal_freq_khz_2 = 36000 / 2; 156 xtal_freq_khz_2 = 36000 / 2;
163 break; 157 break;
164 case FC_XTAL_28_8_MHZ: 158 case FC_XTAL_28_8_MHZ:
165 default: 159 default:
166 xtal_freq_khz_2 = 28800 / 2; 160 xtal_freq_khz_2 = 28800 / 2;
167 break; 161 break;
168 } 162 }
169 163
170 /* select frequency divider and the frequency of VCO */ 164 /* select frequency divider and the frequency of VCO */
171 if (freq < 37084) { /* freq * 96 < 3560000 */ 165 if (freq < 37084) { /* freq * 96 < 3560000 */
172 multi = 96; 166 multi = 96;
173 reg[5] = 0x82; 167 reg[5] = 0x82;
174 reg[6] = 0x00; 168 reg[6] = 0x00;
175 } else if (freq < 55625) { /* freq * 64 < 3560000 */ 169 } else if (freq < 55625) { /* freq * 64 < 3560000 */
176 multi = 64; 170 multi = 64;
177 reg[5] = 0x82; 171 reg[5] = 0x82;
178 reg[6] = 0x02; 172 reg[6] = 0x02;
179 } else if (freq < 74167) { /* freq * 48 < 3560000 */ 173 } else if (freq < 74167) { /* freq * 48 < 3560000 */
180 multi = 48; 174 multi = 48;
181 reg[5] = 0x42; 175 reg[5] = 0x42;
182 reg[6] = 0x00; 176 reg[6] = 0x00;
183 } else if (freq < 111250) { /* freq * 32 < 3560000 */ 177 } else if (freq < 111250) { /* freq * 32 < 3560000 */
184 multi = 32; 178 multi = 32;
185 reg[5] = 0x42; 179 reg[5] = 0x42;
186 reg[6] = 0x02; 180 reg[6] = 0x02;
187 } else if (freq < 148334) { /* freq * 24 < 3560000 */ 181 } else if (freq < 148334) { /* freq * 24 < 3560000 */
188 multi = 24; 182 multi = 24;
189 reg[5] = 0x22; 183 reg[5] = 0x22;
190 reg[6] = 0x00; 184 reg[6] = 0x00;
191 } else if (freq < 222500) { /* freq * 16 < 3560000 */ 185 } else if (freq < 222500) { /* freq * 16 < 3560000 */
192 multi = 16; 186 multi = 16;
193 reg[5] = 0x22; 187 reg[5] = 0x22;
194 reg[6] = 0x02; 188 reg[6] = 0x02;
195 } else if (freq < 296667) { /* freq * 12 < 3560000 */ 189 } else if (freq < 296667) { /* freq * 12 < 3560000 */
196 multi = 12; 190 multi = 12;
197 reg[5] = 0x12; 191 reg[5] = 0x12;
198 reg[6] = 0x00; 192 reg[6] = 0x00;
199 } else if (freq < 445000) { /* freq * 8 < 3560000 */ 193 } else if (freq < 445000) { /* freq * 8 < 3560000 */
200 multi = 8; 194 multi = 8;
201 reg[5] = 0x12; 195 reg[5] = 0x12;
202 reg[6] = 0x02; 196 reg[6] = 0x02;
203 } else if (freq < 593334) { /* freq * 6 < 3560000 */ 197 } else if (freq < 593334) { /* freq * 6 < 3560000 */
204 multi = 6; 198 multi = 6;
205 reg[5] = 0x0a; 199 reg[5] = 0x0a;
206 reg[6] = 0x00; 200 reg[6] = 0x00;
207 } else { 201 } else {
208 multi = 4; 202 multi = 4;
209 reg[5] = 0x0a; 203 reg[5] = 0x0a;
210 reg[6] = 0x02; 204 reg[6] = 0x02;
211 } 205 }
212 206
213 f_vco = freq * multi; 207 f_vco = freq * multi;
214 208
215 if (f_vco >= 3060000) { 209 if (f_vco >= 3060000) {
216 reg[6] |= 0x08; 210 reg[6] |= 0x08;
217 vco_select = true; 211 vco_select = true;
218 } 212 }
219 213
220 if (freq >= 45000) { 214 if (freq >= 45000) {
221 /* From divided value (XDIV) determined the FA and FP value */ 215 /* From divided value (XDIV) determined the FA and FP value */
222 xdiv = (unsigned short)(f_vco / xtal_freq_khz_2); 216 xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
223 if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2)) 217 if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
224 xdiv++; 218 xdiv++;
225 219
226 pm = (unsigned char)(xdiv / 8); 220 pm = (unsigned char)(xdiv / 8);
227 am = (unsigned char)(xdiv - (8 * pm)); 221 am = (unsigned char)(xdiv - (8 * pm));
228 222
229 if (am < 2) { 223 if (am < 2) {
230 reg[1] = am + 8; 224 reg[1] = am + 8;
231 reg[2] = pm - 1; 225 reg[2] = pm - 1;
232 } else { 226 } else {
233 reg[1] = am; 227 reg[1] = am;
234 reg[2] = pm; 228 reg[2] = pm;
235 } 229 }
236 } else { 230 } else {
237 /* fix for frequency less than 45 MHz */ 231 /* fix for frequency less than 45 MHz */
238 reg[1] = 0x06; 232 reg[1] = 0x06;
239 reg[2] = 0x11; 233 reg[2] = 0x11;
240 } 234 }
241 235
242 /* fix clock out */ 236 /* fix clock out */
243 reg[6] |= 0x20; 237 reg[6] |= 0x20;
244 238
245 /* From VCO frequency determines the XIN ( fractional part of Delta 239 /* From VCO frequency determines the XIN ( fractional part of Delta
246 Sigma PLL) and divided value (XDIV) */ 240 Sigma PLL) and divided value (XDIV) */
247 xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2); 241 xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
248 xin = (xin << 15) / xtal_freq_khz_2; 242 xin = (xin << 15) / xtal_freq_khz_2;
249 if (xin >= 16384) 243 if (xin >= 16384)
250 xin += 32768; 244 xin += 32768;
251 245
252 reg[3] = xin >> 8; /* xin with 9 bit resolution */ 246 reg[3] = xin >> 8; /* xin with 9 bit resolution */
253 reg[4] = xin & 0xff; 247 reg[4] = xin & 0xff;
254 248
255 if (delsys == SYS_DVBT) { 249 if (delsys == SYS_DVBT) {
256 reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */ 250 reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
257 switch (p->bandwidth_hz) { 251 switch (p->bandwidth_hz) {
258 case 6000000: 252 case 6000000:
259 reg[6] |= 0x80; 253 reg[6] |= 0x80;
260 break; 254 break;
261 case 7000000: 255 case 7000000:
262 reg[6] |= 0x40; 256 reg[6] |= 0x40;
263 break; 257 break;
264 case 8000000: 258 case 8000000:
265 default: 259 default:
266 break; 260 break;
267 } 261 }
268 } else { 262 } else {
269 dev_err(&priv->i2c->dev, "%s: modulation type not supported!\n", 263 dev_err(&priv->i2c->dev, "%s: modulation type not supported!\n",
270 KBUILD_MODNAME); 264 KBUILD_MODNAME);
271 return -EINVAL; 265 return -EINVAL;
272 } 266 }
273 267
274 /* modified for Realtek demod */ 268 /* modified for Realtek demod */
275 reg[5] |= 0x07; 269 reg[5] |= 0x07;
276 270
277 if (fe->ops.i2c_gate_ctrl) 271 if (fe->ops.i2c_gate_ctrl)
278 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ 272 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
279 273
280 for (i = 1; i <= 6; i++) { 274 for (i = 1; i <= 6; i++) {
281 ret = fc0012_writereg(priv, i, reg[i]); 275 ret = fc0012_writereg(priv, i, reg[i]);
282 if (ret) 276 if (ret)
283 goto exit; 277 goto exit;
284 } 278 }
285 279
286 /* VCO Calibration */ 280 /* VCO Calibration */
287 ret = fc0012_writereg(priv, 0x0e, 0x80); 281 ret = fc0012_writereg(priv, 0x0e, 0x80);
288 if (!ret) 282 if (!ret)
289 ret = fc0012_writereg(priv, 0x0e, 0x00); 283 ret = fc0012_writereg(priv, 0x0e, 0x00);
290 284
291 /* VCO Re-Calibration if needed */ 285 /* VCO Re-Calibration if needed */
292 if (!ret) 286 if (!ret)
293 ret = fc0012_writereg(priv, 0x0e, 0x00); 287 ret = fc0012_writereg(priv, 0x0e, 0x00);
294 288
295 if (!ret) { 289 if (!ret) {
296 msleep(10); 290 msleep(10);
297 ret = fc0012_readreg(priv, 0x0e, &tmp); 291 ret = fc0012_readreg(priv, 0x0e, &tmp);
298 } 292 }
299 if (ret) 293 if (ret)
300 goto exit; 294 goto exit;
301 295
302 /* vco selection */ 296 /* vco selection */
303 tmp &= 0x3f; 297 tmp &= 0x3f;
304 298
305 if (vco_select) { 299 if (vco_select) {
306 if (tmp > 0x3c) { 300 if (tmp > 0x3c) {
307 reg[6] &= ~0x08; 301 reg[6] &= ~0x08;
308 ret = fc0012_writereg(priv, 0x06, reg[6]); 302 ret = fc0012_writereg(priv, 0x06, reg[6]);
309 if (!ret) 303 if (!ret)
310 ret = fc0012_writereg(priv, 0x0e, 0x80); 304 ret = fc0012_writereg(priv, 0x0e, 0x80);
311 if (!ret) 305 if (!ret)
312 ret = fc0012_writereg(priv, 0x0e, 0x00); 306 ret = fc0012_writereg(priv, 0x0e, 0x00);
313 } 307 }
314 } else { 308 } else {
315 if (tmp < 0x02) { 309 if (tmp < 0x02) {
316 reg[6] |= 0x08; 310 reg[6] |= 0x08;
317 ret = fc0012_writereg(priv, 0x06, reg[6]); 311 ret = fc0012_writereg(priv, 0x06, reg[6]);
318 if (!ret) 312 if (!ret)
319 ret = fc0012_writereg(priv, 0x0e, 0x80); 313 ret = fc0012_writereg(priv, 0x0e, 0x80);
320 if (!ret) 314 if (!ret)
321 ret = fc0012_writereg(priv, 0x0e, 0x00); 315 ret = fc0012_writereg(priv, 0x0e, 0x00);
322 } 316 }
323 } 317 }
324 318
325 priv->frequency = p->frequency; 319 priv->frequency = p->frequency;
326 priv->bandwidth = p->bandwidth_hz; 320 priv->bandwidth = p->bandwidth_hz;
327 321
328 exit: 322 exit:
329 if (fe->ops.i2c_gate_ctrl) 323 if (fe->ops.i2c_gate_ctrl)
330 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ 324 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
331 if (ret) 325 if (ret)
332 dev_warn(&priv->i2c->dev, "%s: %s failed: %d\n", 326 dev_warn(&priv->i2c->dev, "%s: %s failed: %d\n",
333 KBUILD_MODNAME, __func__, ret); 327 KBUILD_MODNAME, __func__, ret);
334 return ret; 328 return ret;
335 } 329 }
336 330
337 static int fc0012_get_frequency(struct dvb_frontend *fe, u32 *frequency) 331 static int fc0012_get_frequency(struct dvb_frontend *fe, u32 *frequency)
338 { 332 {
339 struct fc0012_priv *priv = fe->tuner_priv; 333 struct fc0012_priv *priv = fe->tuner_priv;
340 *frequency = priv->frequency; 334 *frequency = priv->frequency;
341 return 0; 335 return 0;
342 } 336 }
343 337
344 static int fc0012_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) 338 static int fc0012_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
345 { 339 {
346 /* CHECK: always ? */ 340 *frequency = 0; /* Zero-IF */
347 *frequency = 0;
348 return 0; 341 return 0;
349 } 342 }
350 343
351 static int fc0012_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) 344 static int fc0012_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
352 { 345 {
353 struct fc0012_priv *priv = fe->tuner_priv; 346 struct fc0012_priv *priv = fe->tuner_priv;
354 *bandwidth = priv->bandwidth; 347 *bandwidth = priv->bandwidth;
355 return 0; 348 return 0;
356 } 349 }
357 350
358 #define INPUT_ADC_LEVEL -8 351 #define INPUT_ADC_LEVEL -8
359 352
360 static int fc0012_get_rf_strength(struct dvb_frontend *fe, u16 *strength) 353 static int fc0012_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
361 { 354 {
362 struct fc0012_priv *priv = fe->tuner_priv; 355 struct fc0012_priv *priv = fe->tuner_priv;
363 int ret; 356 int ret;
364 unsigned char tmp; 357 unsigned char tmp;
365 int int_temp, lna_gain, int_lna, tot_agc_gain, power; 358 int int_temp, lna_gain, int_lna, tot_agc_gain, power;
366 const int fc0012_lna_gain_table[] = { 359 const int fc0012_lna_gain_table[] = {
367 /* low gain */ 360 /* low gain */
368 -63, -58, -99, -73, 361 -63, -58, -99, -73,
369 -63, -65, -54, -60, 362 -63, -65, -54, -60,
370 /* middle gain */ 363 /* middle gain */
371 71, 70, 68, 67, 364 71, 70, 68, 67,
372 65, 63, 61, 58, 365 65, 63, 61, 58,
373 /* high gain */ 366 /* high gain */
374 197, 191, 188, 186, 367 197, 191, 188, 186,
375 184, 182, 181, 179, 368 184, 182, 181, 179,
376 }; 369 };
377 370
378 if (fe->ops.i2c_gate_ctrl) 371 if (fe->ops.i2c_gate_ctrl)
379 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */ 372 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
380 373
381 ret = fc0012_writereg(priv, 0x12, 0x00); 374 ret = fc0012_writereg(priv, 0x12, 0x00);
382 if (ret) 375 if (ret)
383 goto err; 376 goto err;
384 377
385 ret = fc0012_readreg(priv, 0x12, &tmp); 378 ret = fc0012_readreg(priv, 0x12, &tmp);
386 if (ret) 379 if (ret)
387 goto err; 380 goto err;
388 int_temp = tmp; 381 int_temp = tmp;
389 382
390 ret = fc0012_readreg(priv, 0x13, &tmp); 383 ret = fc0012_readreg(priv, 0x13, &tmp);
391 if (ret) 384 if (ret)
392 goto err; 385 goto err;
393 lna_gain = tmp & 0x1f; 386 lna_gain = tmp & 0x1f;
394 387
395 if (fe->ops.i2c_gate_ctrl) 388 if (fe->ops.i2c_gate_ctrl)
396 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ 389 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
397 390
398 if (lna_gain < ARRAY_SIZE(fc0012_lna_gain_table)) { 391 if (lna_gain < ARRAY_SIZE(fc0012_lna_gain_table)) {
399 int_lna = fc0012_lna_gain_table[lna_gain]; 392 int_lna = fc0012_lna_gain_table[lna_gain];
400 tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 + 393 tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
401 (int_temp & 0x1f)) * 2; 394 (int_temp & 0x1f)) * 2;
402 power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10; 395 power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
403 396
404 if (power >= 45) 397 if (power >= 45)
405 *strength = 255; /* 100% */ 398 *strength = 255; /* 100% */
406 else if (power < -95) 399 else if (power < -95)
407 *strength = 0; 400 *strength = 0;
408 else 401 else
409 *strength = (power + 95) * 255 / 140; 402 *strength = (power + 95) * 255 / 140;
410 403
411 *strength |= *strength << 8; 404 *strength |= *strength << 8;
412 } else { 405 } else {
413 ret = -1; 406 ret = -1;
414 } 407 }
415 408
416 goto exit; 409 goto exit;
417 410
418 err: 411 err:
419 if (fe->ops.i2c_gate_ctrl) 412 if (fe->ops.i2c_gate_ctrl)
420 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */ 413 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
421 exit: 414 exit:
422 if (ret) 415 if (ret)
423 dev_warn(&priv->i2c->dev, "%s: %s failed: %d\n", 416 dev_warn(&priv->i2c->dev, "%s: %s failed: %d\n",
424 KBUILD_MODNAME, __func__, ret); 417 KBUILD_MODNAME, __func__, ret);
425 return ret; 418 return ret;
426 } 419 }
427 420
428 static const struct dvb_tuner_ops fc0012_tuner_ops = { 421 static const struct dvb_tuner_ops fc0012_tuner_ops = {
429 .info = { 422 .info = {
430 .name = "Fitipower FC0012", 423 .name = "Fitipower FC0012",
431 424
432 .frequency_min = 37000000, /* estimate */ 425 .frequency_min = 37000000, /* estimate */
433 .frequency_max = 862000000, /* estimate */ 426 .frequency_max = 862000000, /* estimate */
434 .frequency_step = 0, 427 .frequency_step = 0,
435 }, 428 },
436 429
437 .release = fc0012_release, 430 .release = fc0012_release,
438 431
439 .init = fc0012_init, 432 .init = fc0012_init,
440 .sleep = fc0012_sleep,
441 433
442 .set_params = fc0012_set_params, 434 .set_params = fc0012_set_params,
443 435
444 .get_frequency = fc0012_get_frequency, 436 .get_frequency = fc0012_get_frequency,
445 .get_if_frequency = fc0012_get_if_frequency, 437 .get_if_frequency = fc0012_get_if_frequency,
446 .get_bandwidth = fc0012_get_bandwidth, 438 .get_bandwidth = fc0012_get_bandwidth,
447 439
448 .get_rf_strength = fc0012_get_rf_strength, 440 .get_rf_strength = fc0012_get_rf_strength,
449 }; 441 };
450 442
451 struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe, 443 struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
452 struct i2c_adapter *i2c, const struct fc0012_config *cfg) 444 struct i2c_adapter *i2c, const struct fc0012_config *cfg)
453 { 445 {
454 struct fc0012_priv *priv; 446 struct fc0012_priv *priv;
455 int ret; 447 int ret;
456 u8 chip_id; 448 u8 chip_id;
457 449
458 if (fe->ops.i2c_gate_ctrl) 450 if (fe->ops.i2c_gate_ctrl)
459 fe->ops.i2c_gate_ctrl(fe, 1); 451 fe->ops.i2c_gate_ctrl(fe, 1);
460 452
461 priv = kzalloc(sizeof(struct fc0012_priv), GFP_KERNEL); 453 priv = kzalloc(sizeof(struct fc0012_priv), GFP_KERNEL);
462 if (!priv) { 454 if (!priv) {
463 ret = -ENOMEM; 455 ret = -ENOMEM;
464 dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); 456 dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
465 goto err; 457 goto err;
466 } 458 }
467 459
468 priv->cfg = cfg; 460 priv->cfg = cfg;
469 priv->i2c = i2c; 461 priv->i2c = i2c;
470 462
471 /* check if the tuner is there */ 463 /* check if the tuner is there */
472 ret = fc0012_readreg(priv, 0x00, &chip_id); 464 ret = fc0012_readreg(priv, 0x00, &chip_id);
473 if (ret < 0) 465 if (ret < 0)
474 goto err; 466 goto err;
475 467
476 dev_dbg(&i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id); 468 dev_dbg(&i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
477 469
478 switch (chip_id) { 470 switch (chip_id) {
479 case 0xa1: 471 case 0xa1:
480 break; 472 break;
481 default: 473 default:
482 ret = -ENODEV; 474 ret = -ENODEV;
483 goto err; 475 goto err;
484 } 476 }
485 477
486 dev_info(&i2c->dev, "%s: Fitipower FC0012 successfully identified\n", 478 dev_info(&i2c->dev, "%s: Fitipower FC0012 successfully identified\n",
487 KBUILD_MODNAME); 479 KBUILD_MODNAME);
488 480
489 if (priv->cfg->loop_through) { 481 if (priv->cfg->loop_through) {
490 ret = fc0012_writereg(priv, 0x09, 0x6f); 482 ret = fc0012_writereg(priv, 0x09, 0x6f);
491 if (ret < 0) 483 if (ret < 0)
492 goto err; 484 goto err;
493 } 485 }
494 486
495 /* 487 /*
496 * TODO: Clock out en or div? 488 * TODO: Clock out en or div?
497 * For dual tuner configuration clearing bit [0] is required. 489 * For dual tuner configuration clearing bit [0] is required.
498 */ 490 */
499 if (priv->cfg->clock_out) { 491 if (priv->cfg->clock_out) {
500 ret = fc0012_writereg(priv, 0x0b, 0x82); 492 ret = fc0012_writereg(priv, 0x0b, 0x82);
501 if (ret < 0) 493 if (ret < 0)
502 goto err; 494 goto err;
503 } 495 }
504 496
505 fe->tuner_priv = priv; 497 fe->tuner_priv = priv;
506 memcpy(&fe->ops.tuner_ops, &fc0012_tuner_ops, 498 memcpy(&fe->ops.tuner_ops, &fc0012_tuner_ops,
507 sizeof(struct dvb_tuner_ops)); 499 sizeof(struct dvb_tuner_ops));
508 500
509 err: 501 err:
510 if (fe->ops.i2c_gate_ctrl) 502 if (fe->ops.i2c_gate_ctrl)
511 fe->ops.i2c_gate_ctrl(fe, 0); 503 fe->ops.i2c_gate_ctrl(fe, 0);
512 504
513 if (ret) { 505 if (ret) {
514 dev_dbg(&i2c->dev, "%s: failed: %d\n", __func__, ret); 506 dev_dbg(&i2c->dev, "%s: failed: %d\n", __func__, ret);
515 kfree(priv); 507 kfree(priv);
516 return NULL; 508 return NULL;
517 } 509 }
518 510
519 return fe; 511 return fe;
520 } 512 }
521 EXPORT_SYMBOL(fc0012_attach); 513 EXPORT_SYMBOL(fc0012_attach);
522 514
523 MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver"); 515 MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver");
524 MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>"); 516 MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
525 MODULE_LICENSE("GPL"); 517 MODULE_LICENSE("GPL");
526 MODULE_VERSION("0.6"); 518 MODULE_VERSION("0.6");
527 519