]>
Commit | Line | Data |
---|---|---|
c942fddf | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
825b9670 | 2 | /* |
c89f66f6 | 3 | * Afatech AF9013 demodulator driver |
825b9670 AP |
4 | * |
5 | * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> | |
f571e004 | 6 | * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> |
825b9670 AP |
7 | * |
8 | * Thanks to Afatech who kindly provided information. | |
825b9670 AP |
9 | */ |
10 | ||
825b9670 | 11 | #include "af9013_priv.h" |
825b9670 | 12 | |
825b9670 | 13 | struct af9013_state { |
82d1ce3e | 14 | struct i2c_client *client; |
f458a1bc | 15 | struct regmap *regmap; |
22e59e72 | 16 | struct i2c_mux_core *muxc; |
f571e004 | 17 | struct dvb_frontend fe; |
a4e2b6fe AP |
18 | u32 clk; |
19 | u8 tuner; | |
20 | u32 if_frequency; | |
21 | u8 ts_mode; | |
eaa455f0 | 22 | u8 ts_output_pin; |
a4e2b6fe AP |
23 | bool spec_inv; |
24 | u8 api_version[4]; | |
25 | u8 gpio[4]; | |
825b9670 | 26 | |
f571e004 | 27 | u32 bandwidth_hz; |
0df289a2 | 28 | enum fe_status fe_status; |
943a720f AP |
29 | /* RF and IF AGC limits used for signal strength calc */ |
30 | u8 strength_en, rf_agc_50, rf_agc_80, if_agc_50, if_agc_80; | |
f571e004 AP |
31 | unsigned long set_frontend_jiffies; |
32 | unsigned long read_status_jiffies; | |
943a720f | 33 | unsigned long strength_jiffies; |
f3bb7e22 | 34 | unsigned long cnr_jiffies; |
233f3ef7 | 35 | unsigned long ber_ucb_jiffies; |
b911fc89 AP |
36 | u16 dvbv3_snr; |
37 | u16 dvbv3_strength; | |
38 | u32 dvbv3_ber; | |
39 | u32 dvbv3_ucblocks; | |
f571e004 | 40 | bool first_tune; |
825b9670 AP |
41 | }; |
42 | ||
825b9670 AP |
43 | static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) |
44 | { | |
cbb2a299 | 45 | struct i2c_client *client = state->client; |
825b9670 AP |
46 | int ret; |
47 | u8 pos; | |
48 | u16 addr; | |
825b9670 | 49 | |
cbb2a299 | 50 | dev_dbg(&client->dev, "gpio %u, gpioval %02x\n", gpio, gpioval); |
f571e004 AP |
51 | |
52 | /* | |
53 | * GPIO0 & GPIO1 0xd735 | |
54 | * GPIO2 & GPIO3 0xd736 | |
55 | */ | |
825b9670 AP |
56 | |
57 | switch (gpio) { | |
58 | case 0: | |
59 | case 1: | |
60 | addr = 0xd735; | |
61 | break; | |
62 | case 2: | |
63 | case 3: | |
64 | addr = 0xd736; | |
65 | break; | |
66 | ||
67 | default: | |
825b9670 | 68 | ret = -EINVAL; |
f571e004 | 69 | goto err; |
c2c1b415 | 70 | } |
825b9670 AP |
71 | |
72 | switch (gpio) { | |
73 | case 0: | |
74 | case 2: | |
75 | pos = 0; | |
76 | break; | |
77 | case 1: | |
78 | case 3: | |
79 | default: | |
80 | pos = 4; | |
81 | break; | |
c2c1b415 | 82 | } |
825b9670 | 83 | |
f458a1bc AP |
84 | ret = regmap_update_bits(state->regmap, addr, 0x0f << pos, |
85 | gpioval << pos); | |
f571e004 AP |
86 | if (ret) |
87 | goto err; | |
825b9670 | 88 | |
bf69e072 | 89 | return 0; |
f571e004 | 90 | err: |
cbb2a299 | 91 | dev_dbg(&client->dev, "failed %d\n", ret); |
825b9670 AP |
92 | return ret; |
93 | } | |
94 | ||
f571e004 AP |
95 | static int af9013_get_tune_settings(struct dvb_frontend *fe, |
96 | struct dvb_frontend_tune_settings *fesettings) | |
97 | { | |
98 | fesettings->min_delay_ms = 800; | |
99 | fesettings->step_size = 0; | |
100 | fesettings->max_drift = 0; | |
101 | ||
102 | return 0; | |
103 | } | |
104 | ||
59d3cc19 | 105 | static int af9013_set_frontend(struct dvb_frontend *fe) |
f571e004 AP |
106 | { |
107 | struct af9013_state *state = fe->demodulator_priv; | |
cbb2a299 | 108 | struct i2c_client *client = state->client; |
f571e004 AP |
109 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
110 | int ret, i, sampling_freq; | |
111 | bool auto_mode, spec_inv; | |
112 | u8 buf[6]; | |
113 | u32 if_frequency, freq_cw; | |
114 | ||
cbb2a299 AP |
115 | dev_dbg(&client->dev, "frequency %u, bandwidth_hz %u\n", |
116 | c->frequency, c->bandwidth_hz); | |
f571e004 AP |
117 | |
118 | /* program tuner */ | |
bf69e072 AP |
119 | if (fe->ops.tuner_ops.set_params) { |
120 | ret = fe->ops.tuner_ops.set_params(fe); | |
121 | if (ret) | |
122 | goto err; | |
123 | } | |
f571e004 AP |
124 | |
125 | /* program CFOE coefficients */ | |
126 | if (c->bandwidth_hz != state->bandwidth_hz) { | |
127 | for (i = 0; i < ARRAY_SIZE(coeff_lut); i++) { | |
a4e2b6fe | 128 | if (coeff_lut[i].clock == state->clk && |
f571e004 AP |
129 | coeff_lut[i].bandwidth_hz == c->bandwidth_hz) { |
130 | break; | |
131 | } | |
825b9670 AP |
132 | } |
133 | ||
d7b76c91 | 134 | /* Return an error if can't find bandwidth or the right clock */ |
bf69e072 AP |
135 | if (i == ARRAY_SIZE(coeff_lut)) { |
136 | ret = -EINVAL; | |
137 | goto err; | |
138 | } | |
d7b76c91 | 139 | |
f458a1bc AP |
140 | ret = regmap_bulk_write(state->regmap, 0xae00, coeff_lut[i].val, |
141 | sizeof(coeff_lut[i].val)); | |
88c0530f GS |
142 | if (ret) |
143 | goto err; | |
f571e004 | 144 | } |
6d42b218 | 145 | |
f571e004 AP |
146 | /* program frequency control */ |
147 | if (c->bandwidth_hz != state->bandwidth_hz || state->first_tune) { | |
6d42b218 | 148 | /* get used IF frequency */ |
bf69e072 AP |
149 | if (fe->ops.tuner_ops.get_if_frequency) { |
150 | ret = fe->ops.tuner_ops.get_if_frequency(fe, | |
151 | &if_frequency); | |
152 | if (ret) | |
153 | goto err; | |
154 | } else { | |
a4e2b6fe | 155 | if_frequency = state->if_frequency; |
bf69e072 | 156 | } |
825b9670 | 157 | |
cbb2a299 | 158 | dev_dbg(&client->dev, "if_frequency %u\n", if_frequency); |
ab2e06ac | 159 | |
f571e004 | 160 | sampling_freq = if_frequency; |
825b9670 | 161 | |
a4e2b6fe AP |
162 | while (sampling_freq > (state->clk / 2)) |
163 | sampling_freq -= state->clk; | |
825b9670 | 164 | |
f571e004 AP |
165 | if (sampling_freq < 0) { |
166 | sampling_freq *= -1; | |
a4e2b6fe | 167 | spec_inv = state->spec_inv; |
f571e004 | 168 | } else { |
a4e2b6fe | 169 | spec_inv = !state->spec_inv; |
f571e004 | 170 | } |
825b9670 | 171 | |
903b0e58 AP |
172 | freq_cw = DIV_ROUND_CLOSEST_ULL((u64)sampling_freq * 0x800000, |
173 | state->clk); | |
825b9670 | 174 | |
f571e004 AP |
175 | if (spec_inv) |
176 | freq_cw = 0x800000 - freq_cw; | |
825b9670 | 177 | |
f571e004 AP |
178 | buf[0] = (freq_cw >> 0) & 0xff; |
179 | buf[1] = (freq_cw >> 8) & 0xff; | |
180 | buf[2] = (freq_cw >> 16) & 0x7f; | |
825b9670 | 181 | |
f571e004 | 182 | freq_cw = 0x800000 - freq_cw; |
825b9670 | 183 | |
f571e004 AP |
184 | buf[3] = (freq_cw >> 0) & 0xff; |
185 | buf[4] = (freq_cw >> 8) & 0xff; | |
186 | buf[5] = (freq_cw >> 16) & 0x7f; | |
187 | ||
f458a1bc | 188 | ret = regmap_bulk_write(state->regmap, 0xd140, buf, 3); |
f571e004 AP |
189 | if (ret) |
190 | goto err; | |
191 | ||
f458a1bc | 192 | ret = regmap_bulk_write(state->regmap, 0x9be7, buf, 6); |
f571e004 AP |
193 | if (ret) |
194 | goto err; | |
825b9670 | 195 | } |
825b9670 | 196 | |
f571e004 | 197 | /* clear TPS lock flag */ |
f458a1bc | 198 | ret = regmap_update_bits(state->regmap, 0xd330, 0x08, 0x08); |
f571e004 AP |
199 | if (ret) |
200 | goto err; | |
825b9670 | 201 | |
f571e004 | 202 | /* clear MPEG2 lock flag */ |
f458a1bc | 203 | ret = regmap_update_bits(state->regmap, 0xd507, 0x40, 0x00); |
f571e004 AP |
204 | if (ret) |
205 | goto err; | |
a2f5a811 | 206 | |
f571e004 | 207 | /* empty channel function */ |
f458a1bc | 208 | ret = regmap_update_bits(state->regmap, 0x9bfe, 0x01, 0x00); |
f571e004 AP |
209 | if (ret) |
210 | goto err; | |
211 | ||
212 | /* empty DVB-T channel function */ | |
f458a1bc | 213 | ret = regmap_update_bits(state->regmap, 0x9bc2, 0x01, 0x00); |
f571e004 AP |
214 | if (ret) |
215 | goto err; | |
216 | ||
217 | /* transmission parameters */ | |
218 | auto_mode = false; | |
219 | memset(buf, 0, 3); | |
220 | ||
221 | switch (c->transmission_mode) { | |
825b9670 | 222 | case TRANSMISSION_MODE_AUTO: |
6a5e7fde | 223 | auto_mode = true; |
f571e004 | 224 | break; |
825b9670 AP |
225 | case TRANSMISSION_MODE_2K: |
226 | break; | |
227 | case TRANSMISSION_MODE_8K: | |
228 | buf[0] |= (1 << 0); | |
229 | break; | |
230 | default: | |
cbb2a299 | 231 | dev_dbg(&client->dev, "invalid transmission_mode\n"); |
6a5e7fde | 232 | auto_mode = true; |
825b9670 AP |
233 | } |
234 | ||
f571e004 | 235 | switch (c->guard_interval) { |
825b9670 | 236 | case GUARD_INTERVAL_AUTO: |
6a5e7fde | 237 | auto_mode = true; |
f571e004 | 238 | break; |
825b9670 AP |
239 | case GUARD_INTERVAL_1_32: |
240 | break; | |
241 | case GUARD_INTERVAL_1_16: | |
242 | buf[0] |= (1 << 2); | |
243 | break; | |
244 | case GUARD_INTERVAL_1_8: | |
245 | buf[0] |= (2 << 2); | |
246 | break; | |
247 | case GUARD_INTERVAL_1_4: | |
248 | buf[0] |= (3 << 2); | |
249 | break; | |
250 | default: | |
cbb2a299 | 251 | dev_dbg(&client->dev, "invalid guard_interval\n"); |
6a5e7fde | 252 | auto_mode = true; |
825b9670 AP |
253 | } |
254 | ||
f571e004 | 255 | switch (c->hierarchy) { |
825b9670 | 256 | case HIERARCHY_AUTO: |
6a5e7fde | 257 | auto_mode = true; |
f571e004 | 258 | break; |
825b9670 AP |
259 | case HIERARCHY_NONE: |
260 | break; | |
261 | case HIERARCHY_1: | |
262 | buf[0] |= (1 << 4); | |
263 | break; | |
264 | case HIERARCHY_2: | |
265 | buf[0] |= (2 << 4); | |
266 | break; | |
267 | case HIERARCHY_4: | |
268 | buf[0] |= (3 << 4); | |
269 | break; | |
270 | default: | |
cbb2a299 | 271 | dev_dbg(&client->dev, "invalid hierarchy\n"); |
6a5e7fde | 272 | auto_mode = true; |
c2c1b415 | 273 | } |
825b9670 | 274 | |
f571e004 | 275 | switch (c->modulation) { |
825b9670 | 276 | case QAM_AUTO: |
6a5e7fde | 277 | auto_mode = true; |
f571e004 | 278 | break; |
825b9670 AP |
279 | case QPSK: |
280 | break; | |
281 | case QAM_16: | |
282 | buf[1] |= (1 << 6); | |
283 | break; | |
284 | case QAM_64: | |
285 | buf[1] |= (2 << 6); | |
286 | break; | |
287 | default: | |
cbb2a299 | 288 | dev_dbg(&client->dev, "invalid modulation\n"); |
6a5e7fde | 289 | auto_mode = true; |
825b9670 AP |
290 | } |
291 | ||
292 | /* Use HP. How and which case we can switch to LP? */ | |
293 | buf[1] |= (1 << 4); | |
294 | ||
f571e004 | 295 | switch (c->code_rate_HP) { |
825b9670 | 296 | case FEC_AUTO: |
6a5e7fde | 297 | auto_mode = true; |
f571e004 | 298 | break; |
825b9670 AP |
299 | case FEC_1_2: |
300 | break; | |
301 | case FEC_2_3: | |
302 | buf[2] |= (1 << 0); | |
303 | break; | |
304 | case FEC_3_4: | |
305 | buf[2] |= (2 << 0); | |
306 | break; | |
307 | case FEC_5_6: | |
308 | buf[2] |= (3 << 0); | |
309 | break; | |
310 | case FEC_7_8: | |
311 | buf[2] |= (4 << 0); | |
312 | break; | |
313 | default: | |
cbb2a299 | 314 | dev_dbg(&client->dev, "invalid code_rate_HP\n"); |
6a5e7fde | 315 | auto_mode = true; |
825b9670 AP |
316 | } |
317 | ||
f571e004 | 318 | switch (c->code_rate_LP) { |
825b9670 | 319 | case FEC_AUTO: |
6a5e7fde | 320 | auto_mode = true; |
f571e004 | 321 | break; |
825b9670 AP |
322 | case FEC_1_2: |
323 | break; | |
324 | case FEC_2_3: | |
325 | buf[2] |= (1 << 3); | |
326 | break; | |
327 | case FEC_3_4: | |
328 | buf[2] |= (2 << 3); | |
329 | break; | |
330 | case FEC_5_6: | |
331 | buf[2] |= (3 << 3); | |
332 | break; | |
333 | case FEC_7_8: | |
334 | buf[2] |= (4 << 3); | |
335 | break; | |
336 | case FEC_NONE: | |
f571e004 | 337 | break; |
825b9670 | 338 | default: |
cbb2a299 | 339 | dev_dbg(&client->dev, "invalid code_rate_LP\n"); |
6a5e7fde | 340 | auto_mode = true; |
825b9670 AP |
341 | } |
342 | ||
f571e004 AP |
343 | switch (c->bandwidth_hz) { |
344 | case 6000000: | |
825b9670 | 345 | break; |
f571e004 | 346 | case 7000000: |
825b9670 AP |
347 | buf[1] |= (1 << 2); |
348 | break; | |
f571e004 | 349 | case 8000000: |
825b9670 AP |
350 | buf[1] |= (2 << 2); |
351 | break; | |
352 | default: | |
cbb2a299 | 353 | dev_dbg(&client->dev, "invalid bandwidth_hz\n"); |
f571e004 AP |
354 | ret = -EINVAL; |
355 | goto err; | |
825b9670 AP |
356 | } |
357 | ||
f458a1bc | 358 | ret = regmap_bulk_write(state->regmap, 0xd3c0, buf, 3); |
825b9670 | 359 | if (ret) |
f571e004 | 360 | goto err; |
825b9670 | 361 | |
f571e004 AP |
362 | if (auto_mode) { |
363 | /* clear easy mode flag */ | |
f458a1bc | 364 | ret = regmap_write(state->regmap, 0xaefd, 0x00); |
825b9670 | 365 | if (ret) |
f571e004 | 366 | goto err; |
825b9670 | 367 | |
cbb2a299 | 368 | dev_dbg(&client->dev, "auto params\n"); |
825b9670 | 369 | } else { |
f571e004 | 370 | /* set easy mode flag */ |
f458a1bc | 371 | ret = regmap_write(state->regmap, 0xaefd, 0x01); |
825b9670 | 372 | if (ret) |
f571e004 | 373 | goto err; |
825b9670 | 374 | |
f458a1bc | 375 | ret = regmap_write(state->regmap, 0xaefe, 0x00); |
825b9670 | 376 | if (ret) |
f571e004 AP |
377 | goto err; |
378 | ||
cbb2a299 | 379 | dev_dbg(&client->dev, "manual params\n"); |
825b9670 | 380 | } |
825b9670 | 381 | |
f458a1bc AP |
382 | /* Reset FSM */ |
383 | ret = regmap_write(state->regmap, 0xffff, 0x00); | |
825b9670 | 384 | if (ret) |
f571e004 AP |
385 | goto err; |
386 | ||
387 | state->bandwidth_hz = c->bandwidth_hz; | |
388 | state->set_frontend_jiffies = jiffies; | |
389 | state->first_tune = false; | |
825b9670 | 390 | |
bf69e072 | 391 | return 0; |
f571e004 | 392 | err: |
cbb2a299 | 393 | dev_dbg(&client->dev, "failed %d\n", ret); |
825b9670 AP |
394 | return ret; |
395 | } | |
396 | ||
7e3e68bc MCC |
397 | static int af9013_get_frontend(struct dvb_frontend *fe, |
398 | struct dtv_frontend_properties *c) | |
825b9670 AP |
399 | { |
400 | struct af9013_state *state = fe->demodulator_priv; | |
cbb2a299 | 401 | struct i2c_client *client = state->client; |
825b9670 | 402 | int ret; |
f571e004 | 403 | u8 buf[3]; |
825b9670 | 404 | |
cbb2a299 | 405 | dev_dbg(&client->dev, "\n"); |
f571e004 | 406 | |
f458a1bc | 407 | ret = regmap_bulk_read(state->regmap, 0xd3c0, buf, 3); |
f571e004 AP |
408 | if (ret) |
409 | goto err; | |
825b9670 AP |
410 | |
411 | switch ((buf[1] >> 6) & 3) { | |
412 | case 0: | |
f571e004 | 413 | c->modulation = QPSK; |
825b9670 AP |
414 | break; |
415 | case 1: | |
f571e004 | 416 | c->modulation = QAM_16; |
825b9670 AP |
417 | break; |
418 | case 2: | |
f571e004 | 419 | c->modulation = QAM_64; |
825b9670 AP |
420 | break; |
421 | } | |
422 | ||
423 | switch ((buf[0] >> 0) & 3) { | |
424 | case 0: | |
f571e004 | 425 | c->transmission_mode = TRANSMISSION_MODE_2K; |
825b9670 AP |
426 | break; |
427 | case 1: | |
f571e004 | 428 | c->transmission_mode = TRANSMISSION_MODE_8K; |
825b9670 AP |
429 | } |
430 | ||
431 | switch ((buf[0] >> 2) & 3) { | |
432 | case 0: | |
6a2329ad | 433 | c->guard_interval = GUARD_INTERVAL_1_32; |
825b9670 AP |
434 | break; |
435 | case 1: | |
6a2329ad | 436 | c->guard_interval = GUARD_INTERVAL_1_16; |
825b9670 AP |
437 | break; |
438 | case 2: | |
6a2329ad | 439 | c->guard_interval = GUARD_INTERVAL_1_8; |
825b9670 AP |
440 | break; |
441 | case 3: | |
6a2329ad | 442 | c->guard_interval = GUARD_INTERVAL_1_4; |
825b9670 AP |
443 | break; |
444 | } | |
445 | ||
446 | switch ((buf[0] >> 4) & 7) { | |
447 | case 0: | |
f571e004 | 448 | c->hierarchy = HIERARCHY_NONE; |
825b9670 AP |
449 | break; |
450 | case 1: | |
f571e004 | 451 | c->hierarchy = HIERARCHY_1; |
825b9670 AP |
452 | break; |
453 | case 2: | |
f571e004 | 454 | c->hierarchy = HIERARCHY_2; |
825b9670 AP |
455 | break; |
456 | case 3: | |
f571e004 | 457 | c->hierarchy = HIERARCHY_4; |
825b9670 AP |
458 | break; |
459 | } | |
460 | ||
461 | switch ((buf[2] >> 0) & 7) { | |
462 | case 0: | |
f571e004 | 463 | c->code_rate_HP = FEC_1_2; |
825b9670 AP |
464 | break; |
465 | case 1: | |
f571e004 AP |
466 | c->code_rate_HP = FEC_2_3; |
467 | break; | |
468 | case 2: | |
469 | c->code_rate_HP = FEC_3_4; | |
470 | break; | |
471 | case 3: | |
472 | c->code_rate_HP = FEC_5_6; | |
473 | break; | |
474 | case 4: | |
475 | c->code_rate_HP = FEC_7_8; | |
476 | break; | |
825b9670 AP |
477 | } |
478 | ||
f571e004 AP |
479 | switch ((buf[2] >> 3) & 7) { |
480 | case 0: | |
481 | c->code_rate_LP = FEC_1_2; | |
482 | break; | |
483 | case 1: | |
484 | c->code_rate_LP = FEC_2_3; | |
485 | break; | |
486 | case 2: | |
487 | c->code_rate_LP = FEC_3_4; | |
488 | break; | |
489 | case 3: | |
490 | c->code_rate_LP = FEC_5_6; | |
491 | break; | |
492 | case 4: | |
493 | c->code_rate_LP = FEC_7_8; | |
494 | break; | |
495 | } | |
825b9670 | 496 | |
f571e004 AP |
497 | switch ((buf[1] >> 2) & 3) { |
498 | case 0: | |
499 | c->bandwidth_hz = 6000000; | |
500 | break; | |
501 | case 1: | |
502 | c->bandwidth_hz = 7000000; | |
503 | break; | |
504 | case 2: | |
505 | c->bandwidth_hz = 8000000; | |
506 | break; | |
825b9670 AP |
507 | } |
508 | ||
bf69e072 | 509 | return 0; |
f571e004 | 510 | err: |
cbb2a299 | 511 | dev_dbg(&client->dev, "failed %d\n", ret); |
825b9670 AP |
512 | return ret; |
513 | } | |
514 | ||
0df289a2 | 515 | static int af9013_read_status(struct dvb_frontend *fe, enum fe_status *status) |
825b9670 AP |
516 | { |
517 | struct af9013_state *state = fe->demodulator_priv; | |
cbb2a299 | 518 | struct i2c_client *client = state->client; |
943a720f AP |
519 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
520 | int ret, stmp1; | |
521 | unsigned int utmp, utmp1, utmp2, utmp3, utmp4; | |
233f3ef7 | 522 | u8 buf[7]; |
943a720f AP |
523 | |
524 | dev_dbg(&client->dev, "\n"); | |
f571e004 AP |
525 | |
526 | /* | |
527 | * Return status from the cache if it is younger than 2000ms with the | |
528 | * exception of last tune is done during 4000ms. | |
529 | */ | |
7903fbe3 AP |
530 | if (time_is_after_jiffies(state->read_status_jiffies + msecs_to_jiffies(2000)) && |
531 | time_is_before_jiffies(state->set_frontend_jiffies + msecs_to_jiffies(4000))) { | |
532 | *status = state->fe_status; | |
f571e004 | 533 | } else { |
7903fbe3 AP |
534 | /* MPEG2 lock */ |
535 | ret = regmap_read(state->regmap, 0xd507, &utmp); | |
536 | if (ret) | |
537 | goto err; | |
825b9670 | 538 | |
7903fbe3 AP |
539 | if ((utmp >> 6) & 0x01) { |
540 | utmp1 = FE_HAS_SIGNAL | FE_HAS_CARRIER | | |
541 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | |
542 | } else { | |
543 | /* TPS lock */ | |
544 | ret = regmap_read(state->regmap, 0xd330, &utmp); | |
545 | if (ret) | |
546 | goto err; | |
f571e004 | 547 | |
7903fbe3 AP |
548 | if ((utmp >> 3) & 0x01) |
549 | utmp1 = FE_HAS_SIGNAL | FE_HAS_CARRIER | | |
550 | FE_HAS_VITERBI; | |
551 | else | |
552 | utmp1 = 0; | |
553 | } | |
825b9670 | 554 | |
7903fbe3 | 555 | dev_dbg(&client->dev, "fe_status %02x\n", utmp1); |
f571e004 | 556 | |
7903fbe3 | 557 | state->read_status_jiffies = jiffies; |
825b9670 | 558 | |
7903fbe3 AP |
559 | state->fe_status = utmp1; |
560 | *status = utmp1; | |
561 | } | |
825b9670 | 562 | |
943a720f AP |
563 | /* Signal strength */ |
564 | switch (state->strength_en) { | |
565 | case 0: | |
566 | /* Check if we support signal strength */ | |
567 | ret = regmap_read(state->regmap, 0x9bee, &utmp); | |
568 | if (ret) | |
569 | goto err; | |
570 | ||
571 | if ((utmp >> 0) & 0x01) { | |
572 | /* Read agc values for signal strength estimation */ | |
573 | ret = regmap_read(state->regmap, 0x9bbd, &utmp1); | |
574 | if (ret) | |
575 | goto err; | |
576 | ret = regmap_read(state->regmap, 0x9bd0, &utmp2); | |
577 | if (ret) | |
578 | goto err; | |
579 | ret = regmap_read(state->regmap, 0x9be2, &utmp3); | |
580 | if (ret) | |
581 | goto err; | |
582 | ret = regmap_read(state->regmap, 0x9be4, &utmp4); | |
583 | if (ret) | |
584 | goto err; | |
585 | ||
586 | state->rf_agc_50 = utmp1; | |
587 | state->rf_agc_80 = utmp2; | |
588 | state->if_agc_50 = utmp3; | |
589 | state->if_agc_80 = utmp4; | |
590 | dev_dbg(&client->dev, | |
591 | "rf_agc_50 %u, rf_agc_80 %u, if_agc_50 %u, if_agc_80 %u\n", | |
592 | utmp1, utmp2, utmp3, utmp4); | |
593 | ||
594 | state->strength_en = 1; | |
595 | } else { | |
596 | /* Signal strength is not supported */ | |
597 | state->strength_en = 2; | |
598 | break; | |
599 | } | |
600 | /* Fall through */ | |
601 | case 1: | |
602 | if (time_is_after_jiffies(state->strength_jiffies + msecs_to_jiffies(2000))) | |
603 | break; | |
604 | ||
605 | /* Read value */ | |
606 | ret = regmap_bulk_read(state->regmap, 0xd07c, buf, 2); | |
607 | if (ret) | |
608 | goto err; | |
609 | ||
610 | /* | |
611 | * Construct line equation from tuner dependent -80/-50 dBm agc | |
612 | * limits and use it to map current agc value to dBm estimate | |
613 | */ | |
614 | #define agc_gain (buf[0] + buf[1]) | |
615 | #define agc_gain_50dbm (state->rf_agc_50 + state->if_agc_50) | |
616 | #define agc_gain_80dbm (state->rf_agc_80 + state->if_agc_80) | |
617 | stmp1 = 30000 * (agc_gain - agc_gain_80dbm) / | |
618 | (agc_gain_50dbm - agc_gain_80dbm) - 80000; | |
619 | ||
620 | dev_dbg(&client->dev, | |
621 | "strength %d, agc_gain %d, agc_gain_50dbm %d, agc_gain_80dbm %d\n", | |
622 | stmp1, agc_gain, agc_gain_50dbm, agc_gain_80dbm); | |
623 | ||
624 | state->strength_jiffies = jiffies; | |
b911fc89 AP |
625 | /* Convert [-90, -30] dBm to [0x0000, 0xffff] for dvbv3 */ |
626 | utmp1 = clamp(stmp1 + 90000, 0, 60000); | |
627 | state->dvbv3_strength = div_u64((u64)utmp1 * 0xffff, 60000); | |
943a720f AP |
628 | |
629 | c->strength.stat[0].scale = FE_SCALE_DECIBEL; | |
630 | c->strength.stat[0].svalue = stmp1; | |
631 | break; | |
632 | default: | |
633 | c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | |
634 | break; | |
635 | } | |
636 | ||
f3bb7e22 AP |
637 | /* CNR */ |
638 | switch (state->fe_status & FE_HAS_VITERBI) { | |
639 | case FE_HAS_VITERBI: | |
640 | if (time_is_after_jiffies(state->cnr_jiffies + msecs_to_jiffies(2000))) | |
641 | break; | |
642 | ||
643 | /* Check if cnr ready */ | |
644 | ret = regmap_read(state->regmap, 0xd2e1, &utmp); | |
645 | if (ret) | |
646 | goto err; | |
647 | ||
648 | if (!((utmp >> 3) & 0x01)) { | |
649 | dev_dbg(&client->dev, "cnr not ready\n"); | |
650 | break; | |
651 | } | |
652 | ||
653 | /* Read value */ | |
654 | ret = regmap_bulk_read(state->regmap, 0xd2e3, buf, 3); | |
655 | if (ret) | |
656 | goto err; | |
657 | ||
658 | utmp1 = buf[2] << 16 | buf[1] << 8 | buf[0] << 0; | |
659 | ||
660 | /* Read current modulation */ | |
661 | ret = regmap_read(state->regmap, 0xd3c1, &utmp); | |
662 | if (ret) | |
663 | goto err; | |
664 | ||
665 | switch ((utmp >> 6) & 3) { | |
666 | case 0: | |
667 | /* | |
668 | * QPSK | |
669 | * CNR[dB] 13 * -log10((1690000 - value) / value) + 2.6 | |
670 | * value [653799, 1689999], 2.6 / 13 = 3355443 | |
671 | */ | |
672 | utmp1 = clamp(utmp1, 653799U, 1689999U); | |
673 | utmp1 = ((u64)(intlog10(utmp1) | |
674 | - intlog10(1690000 - utmp1) | |
675 | + 3355443) * 13 * 1000) >> 24; | |
676 | break; | |
677 | case 1: | |
678 | /* | |
679 | * QAM-16 | |
680 | * CNR[dB] 6 * log10((value - 370000) / (828000 - value)) + 15.7 | |
681 | * value [371105, 827999], 15.7 / 6 = 43900382 | |
682 | */ | |
683 | utmp1 = clamp(utmp1, 371105U, 827999U); | |
684 | utmp1 = ((u64)(intlog10(utmp1 - 370000) | |
685 | - intlog10(828000 - utmp1) | |
686 | + 43900382) * 6 * 1000) >> 24; | |
687 | break; | |
688 | case 2: | |
689 | /* | |
690 | * QAM-64 | |
691 | * CNR[dB] 8 * log10((value - 193000) / (425000 - value)) + 23.8 | |
692 | * value [193246, 424999], 23.8 / 8 = 49912218 | |
693 | */ | |
694 | utmp1 = clamp(utmp1, 193246U, 424999U); | |
695 | utmp1 = ((u64)(intlog10(utmp1 - 193000) | |
696 | - intlog10(425000 - utmp1) | |
697 | + 49912218) * 8 * 1000) >> 24; | |
698 | break; | |
699 | default: | |
700 | dev_dbg(&client->dev, "invalid modulation %u\n", | |
701 | (utmp >> 6) & 3); | |
702 | utmp1 = 0; | |
703 | break; | |
704 | } | |
705 | ||
706 | dev_dbg(&client->dev, "cnr %u\n", utmp1); | |
707 | ||
708 | state->cnr_jiffies = jiffies; | |
b911fc89 | 709 | state->dvbv3_snr = utmp1 / 100; |
f3bb7e22 AP |
710 | |
711 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; | |
712 | c->cnr.stat[0].svalue = utmp1; | |
713 | break; | |
714 | default: | |
715 | c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | |
716 | break; | |
717 | } | |
718 | ||
233f3ef7 AP |
719 | /* BER / PER */ |
720 | switch (state->fe_status & FE_HAS_SYNC) { | |
721 | case FE_HAS_SYNC: | |
722 | if (time_is_after_jiffies(state->ber_ucb_jiffies + msecs_to_jiffies(2000))) | |
723 | break; | |
724 | ||
725 | /* Check if ber / ucb is ready */ | |
726 | ret = regmap_read(state->regmap, 0xd391, &utmp); | |
727 | if (ret) | |
728 | goto err; | |
729 | ||
730 | if (!((utmp >> 4) & 0x01)) { | |
731 | dev_dbg(&client->dev, "ber not ready\n"); | |
732 | break; | |
733 | } | |
734 | ||
735 | /* Read value */ | |
736 | ret = regmap_bulk_read(state->regmap, 0xd385, buf, 7); | |
737 | if (ret) | |
738 | goto err; | |
739 | ||
740 | utmp1 = buf[4] << 16 | buf[3] << 8 | buf[2] << 0; | |
741 | utmp2 = (buf[1] << 8 | buf[0] << 0) * 204 * 8; | |
742 | utmp3 = buf[6] << 8 | buf[5] << 0; | |
743 | utmp4 = buf[1] << 8 | buf[0] << 0; | |
744 | ||
745 | /* Use 10000 TS packets for measure */ | |
746 | if (utmp4 != 10000) { | |
747 | buf[0] = (10000 >> 0) & 0xff; | |
748 | buf[1] = (10000 >> 8) & 0xff; | |
749 | ret = regmap_bulk_write(state->regmap, 0xd385, buf, 2); | |
750 | if (ret) | |
751 | goto err; | |
752 | } | |
753 | ||
754 | /* Reset ber / ucb counter */ | |
755 | ret = regmap_update_bits(state->regmap, 0xd391, 0x20, 0x20); | |
756 | if (ret) | |
757 | goto err; | |
758 | ||
759 | dev_dbg(&client->dev, "post_bit_error %u, post_bit_count %u\n", | |
760 | utmp1, utmp2); | |
761 | dev_dbg(&client->dev, "block_error %u, block_count %u\n", | |
762 | utmp3, utmp4); | |
763 | ||
764 | state->ber_ucb_jiffies = jiffies; | |
b911fc89 AP |
765 | state->dvbv3_ber = utmp1; |
766 | state->dvbv3_ucblocks += utmp3; | |
233f3ef7 AP |
767 | |
768 | c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; | |
769 | c->post_bit_error.stat[0].uvalue += utmp1; | |
770 | c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; | |
771 | c->post_bit_count.stat[0].uvalue += utmp2; | |
772 | ||
773 | c->block_error.stat[0].scale = FE_SCALE_COUNTER; | |
774 | c->block_error.stat[0].uvalue += utmp3; | |
775 | c->block_count.stat[0].scale = FE_SCALE_COUNTER; | |
776 | c->block_count.stat[0].uvalue += utmp4; | |
777 | break; | |
778 | default: | |
779 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | |
780 | c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | |
781 | ||
782 | c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | |
783 | c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | |
784 | break; | |
785 | } | |
786 | ||
bf69e072 | 787 | return 0; |
f571e004 | 788 | err: |
cbb2a299 | 789 | dev_dbg(&client->dev, "failed %d\n", ret); |
825b9670 AP |
790 | return ret; |
791 | } | |
792 | ||
f571e004 | 793 | static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr) |
825b9670 AP |
794 | { |
795 | struct af9013_state *state = fe->demodulator_priv; | |
b911fc89 AP |
796 | |
797 | *snr = state->dvbv3_snr; | |
798 | ||
f571e004 | 799 | return 0; |
825b9670 AP |
800 | } |
801 | ||
802 | static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | |
803 | { | |
804 | struct af9013_state *state = fe->demodulator_priv; | |
b911fc89 AP |
805 | |
806 | *strength = state->dvbv3_strength; | |
807 | ||
f571e004 | 808 | return 0; |
825b9670 AP |
809 | } |
810 | ||
f571e004 | 811 | static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber) |
825b9670 AP |
812 | { |
813 | struct af9013_state *state = fe->demodulator_priv; | |
b911fc89 AP |
814 | |
815 | *ber = state->dvbv3_ber; | |
816 | ||
f571e004 | 817 | return 0; |
825b9670 AP |
818 | } |
819 | ||
820 | static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | |
821 | { | |
822 | struct af9013_state *state = fe->demodulator_priv; | |
b911fc89 AP |
823 | |
824 | *ucblocks = state->dvbv3_ucblocks; | |
825 | ||
f571e004 | 826 | return 0; |
825b9670 AP |
827 | } |
828 | ||
829 | static int af9013_init(struct dvb_frontend *fe) | |
830 | { | |
831 | struct af9013_state *state = fe->demodulator_priv; | |
cbb2a299 | 832 | struct i2c_client *client = state->client; |
825b9670 | 833 | int ret, i, len; |
f458a1bc AP |
834 | unsigned int utmp; |
835 | u8 buf[3]; | |
3b536127 | 836 | const struct af9013_reg_mask_val *tab; |
825b9670 | 837 | |
cbb2a299 | 838 | dev_dbg(&client->dev, "\n"); |
825b9670 | 839 | |
cdd19b52 AP |
840 | /* ADC on */ |
841 | ret = regmap_update_bits(state->regmap, 0xd73a, 0x08, 0x00); | |
842 | if (ret) | |
843 | goto err; | |
844 | ||
845 | /* Clear reset */ | |
846 | ret = regmap_update_bits(state->regmap, 0xd417, 0x02, 0x00); | |
847 | if (ret) | |
848 | goto err; | |
849 | ||
850 | /* Disable reset */ | |
851 | ret = regmap_update_bits(state->regmap, 0xd417, 0x10, 0x00); | |
825b9670 | 852 | if (ret) |
f571e004 | 853 | goto err; |
825b9670 | 854 | |
825b9670 | 855 | /* write API version to firmware */ |
f458a1bc | 856 | ret = regmap_bulk_write(state->regmap, 0x9bf2, state->api_version, 4); |
f571e004 AP |
857 | if (ret) |
858 | goto err; | |
825b9670 AP |
859 | |
860 | /* program ADC control */ | |
a4e2b6fe | 861 | switch (state->clk) { |
f571e004 | 862 | case 28800000: /* 28.800 MHz */ |
f458a1bc | 863 | utmp = 0; |
f571e004 AP |
864 | break; |
865 | case 20480000: /* 20.480 MHz */ | |
f458a1bc | 866 | utmp = 1; |
f571e004 AP |
867 | break; |
868 | case 28000000: /* 28.000 MHz */ | |
f458a1bc | 869 | utmp = 2; |
f571e004 AP |
870 | break; |
871 | case 25000000: /* 25.000 MHz */ | |
f458a1bc | 872 | utmp = 3; |
f571e004 AP |
873 | break; |
874 | default: | |
cbb2a299 AP |
875 | ret = -EINVAL; |
876 | goto err; | |
f571e004 AP |
877 | } |
878 | ||
f458a1bc | 879 | ret = regmap_update_bits(state->regmap, 0x9bd2, 0x0f, utmp); |
f571e004 AP |
880 | if (ret) |
881 | goto err; | |
882 | ||
f458a1bc AP |
883 | utmp = div_u64((u64)state->clk * 0x80000, 1000000); |
884 | buf[0] = (utmp >> 0) & 0xff; | |
885 | buf[1] = (utmp >> 8) & 0xff; | |
886 | buf[2] = (utmp >> 16) & 0xff; | |
887 | ret = regmap_bulk_write(state->regmap, 0xd180, buf, 3); | |
825b9670 | 888 | if (ret) |
f571e004 | 889 | goto err; |
825b9670 | 890 | |
3b536127 AP |
891 | /* Demod core settings */ |
892 | dev_dbg(&client->dev, "load demod core settings\n"); | |
893 | len = ARRAY_SIZE(demod_init_tab); | |
894 | tab = demod_init_tab; | |
825b9670 | 895 | for (i = 0; i < len; i++) { |
3b536127 AP |
896 | ret = regmap_update_bits(state->regmap, tab[i].reg, tab[i].mask, |
897 | tab[i].val); | |
825b9670 | 898 | if (ret) |
f571e004 | 899 | goto err; |
825b9670 AP |
900 | } |
901 | ||
3b536127 | 902 | /* Demod tuner specific settings */ |
cbb2a299 | 903 | dev_dbg(&client->dev, "load tuner specific settings\n"); |
a4e2b6fe | 904 | switch (state->tuner) { |
825b9670 | 905 | case AF9013_TUNER_MXL5003D: |
3b536127 AP |
906 | len = ARRAY_SIZE(tuner_init_tab_mxl5003d); |
907 | tab = tuner_init_tab_mxl5003d; | |
825b9670 AP |
908 | break; |
909 | case AF9013_TUNER_MXL5005D: | |
910 | case AF9013_TUNER_MXL5005R: | |
a4f31d0d | 911 | case AF9013_TUNER_MXL5007T: |
3b536127 AP |
912 | len = ARRAY_SIZE(tuner_init_tab_mxl5005); |
913 | tab = tuner_init_tab_mxl5005; | |
825b9670 AP |
914 | break; |
915 | case AF9013_TUNER_ENV77H11D5: | |
3b536127 AP |
916 | len = ARRAY_SIZE(tuner_init_tab_env77h11d5); |
917 | tab = tuner_init_tab_env77h11d5; | |
825b9670 AP |
918 | break; |
919 | case AF9013_TUNER_MT2060: | |
3b536127 AP |
920 | len = ARRAY_SIZE(tuner_init_tab_mt2060); |
921 | tab = tuner_init_tab_mt2060; | |
825b9670 AP |
922 | break; |
923 | case AF9013_TUNER_MC44S803: | |
3b536127 AP |
924 | len = ARRAY_SIZE(tuner_init_tab_mc44s803); |
925 | tab = tuner_init_tab_mc44s803; | |
825b9670 AP |
926 | break; |
927 | case AF9013_TUNER_QT1010: | |
928 | case AF9013_TUNER_QT1010A: | |
3b536127 AP |
929 | len = ARRAY_SIZE(tuner_init_tab_qt1010); |
930 | tab = tuner_init_tab_qt1010; | |
825b9670 AP |
931 | break; |
932 | case AF9013_TUNER_MT2060_2: | |
3b536127 AP |
933 | len = ARRAY_SIZE(tuner_init_tab_mt2060_2); |
934 | tab = tuner_init_tab_mt2060_2; | |
825b9670 AP |
935 | break; |
936 | case AF9013_TUNER_TDA18271: | |
2158e509 | 937 | case AF9013_TUNER_TDA18218: |
3b536127 AP |
938 | len = ARRAY_SIZE(tuner_init_tab_tda18271); |
939 | tab = tuner_init_tab_tda18271; | |
825b9670 AP |
940 | break; |
941 | case AF9013_TUNER_UNKNOWN: | |
942 | default: | |
3b536127 AP |
943 | len = ARRAY_SIZE(tuner_init_tab_unknown); |
944 | tab = tuner_init_tab_unknown; | |
825b9670 AP |
945 | break; |
946 | } | |
947 | ||
948 | for (i = 0; i < len; i++) { | |
3b536127 AP |
949 | ret = regmap_update_bits(state->regmap, tab[i].reg, tab[i].mask, |
950 | tab[i].val); | |
825b9670 | 951 | if (ret) |
f571e004 | 952 | goto err; |
825b9670 AP |
953 | } |
954 | ||
eaa455f0 AP |
955 | /* TS interface */ |
956 | if (state->ts_output_pin == 7) | |
957 | utmp = 1 << 3 | state->ts_mode << 1; | |
958 | else | |
959 | utmp = 0 << 3 | state->ts_mode << 1; | |
960 | ret = regmap_update_bits(state->regmap, 0xd500, 0x0e, utmp); | |
825b9670 | 961 | if (ret) |
f571e004 | 962 | goto err; |
825b9670 AP |
963 | |
964 | /* enable lock led */ | |
f458a1bc | 965 | ret = regmap_update_bits(state->regmap, 0xd730, 0x01, 0x01); |
825b9670 | 966 | if (ret) |
f571e004 | 967 | goto err; |
825b9670 | 968 | |
f571e004 | 969 | state->first_tune = true; |
f571e004 | 970 | |
bf69e072 | 971 | return 0; |
f571e004 | 972 | err: |
cbb2a299 | 973 | dev_dbg(&client->dev, "failed %d\n", ret); |
f571e004 AP |
974 | return ret; |
975 | } | |
976 | ||
977 | static int af9013_sleep(struct dvb_frontend *fe) | |
978 | { | |
979 | struct af9013_state *state = fe->demodulator_priv; | |
cbb2a299 | 980 | struct i2c_client *client = state->client; |
f571e004 | 981 | int ret; |
cdd19b52 | 982 | unsigned int utmp; |
f571e004 | 983 | |
cbb2a299 | 984 | dev_dbg(&client->dev, "\n"); |
f571e004 | 985 | |
f571e004 | 986 | /* disable lock led */ |
f458a1bc | 987 | ret = regmap_update_bits(state->regmap, 0xd730, 0x01, 0x00); |
f571e004 AP |
988 | if (ret) |
989 | goto err; | |
990 | ||
cdd19b52 AP |
991 | /* Enable reset */ |
992 | ret = regmap_update_bits(state->regmap, 0xd417, 0x10, 0x10); | |
993 | if (ret) | |
994 | goto err; | |
995 | ||
996 | /* Start reset execution */ | |
997 | ret = regmap_write(state->regmap, 0xaeff, 0x01); | |
998 | if (ret) | |
999 | goto err; | |
1000 | ||
1001 | /* Wait reset performs */ | |
1002 | ret = regmap_read_poll_timeout(state->regmap, 0xd417, utmp, | |
1003 | (utmp >> 1) & 0x01, 5000, 1000000); | |
1004 | if (ret) | |
1005 | goto err; | |
1006 | ||
1007 | if (!((utmp >> 1) & 0x01)) { | |
1008 | ret = -ETIMEDOUT; | |
1009 | goto err; | |
1010 | } | |
1011 | ||
1012 | /* ADC off */ | |
1013 | ret = regmap_update_bits(state->regmap, 0xd73a, 0x08, 0x08); | |
f571e004 AP |
1014 | if (ret) |
1015 | goto err; | |
1016 | ||
bf69e072 | 1017 | return 0; |
f571e004 | 1018 | err: |
cbb2a299 | 1019 | dev_dbg(&client->dev, "failed %d\n", ret); |
f571e004 AP |
1020 | return ret; |
1021 | } | |
1022 | ||
bd336e63 | 1023 | static const struct dvb_frontend_ops af9013_ops; |
825b9670 AP |
1024 | |
1025 | static int af9013_download_firmware(struct af9013_state *state) | |
1026 | { | |
cbb2a299 | 1027 | struct i2c_client *client = state->client; |
96700d24 | 1028 | int ret, i, len, rem; |
f458a1bc | 1029 | unsigned int utmp; |
96700d24 | 1030 | u8 buf[4]; |
825b9670 | 1031 | u16 checksum = 0; |
96700d24 AP |
1032 | const struct firmware *firmware; |
1033 | const char *name = AF9013_FIRMWARE; | |
825b9670 | 1034 | |
96700d24 AP |
1035 | dev_dbg(&client->dev, "\n"); |
1036 | ||
1037 | /* Check whether firmware is already running */ | |
f458a1bc | 1038 | ret = regmap_read(state->regmap, 0x98be, &utmp); |
825b9670 | 1039 | if (ret) |
f571e004 | 1040 | goto err; |
bf69e072 AP |
1041 | |
1042 | dev_dbg(&client->dev, "firmware status %02x\n", utmp); | |
825b9670 | 1043 | |
96700d24 | 1044 | if (utmp == 0x0c) |
bf69e072 | 1045 | return 0; |
825b9670 | 1046 | |
cbb2a299 AP |
1047 | dev_info(&client->dev, "found a '%s' in cold state, will try to load a firmware\n", |
1048 | af9013_ops.info.name); | |
825b9670 | 1049 | |
96700d24 AP |
1050 | /* Request the firmware, will block and timeout */ |
1051 | ret = request_firmware(&firmware, name, &client->dev); | |
825b9670 | 1052 | if (ret) { |
cbb2a299 | 1053 | dev_info(&client->dev, "firmware file '%s' not found %d\n", |
96700d24 | 1054 | name, ret); |
f571e004 | 1055 | goto err; |
825b9670 AP |
1056 | } |
1057 | ||
cbb2a299 | 1058 | dev_info(&client->dev, "downloading firmware from file '%s'\n", |
96700d24 | 1059 | name); |
825b9670 | 1060 | |
96700d24 AP |
1061 | /* Write firmware checksum & size */ |
1062 | for (i = 0; i < firmware->size; i++) | |
1063 | checksum += firmware->data[i]; | |
f458a1bc | 1064 | |
96700d24 AP |
1065 | buf[0] = (checksum >> 8) & 0xff; |
1066 | buf[1] = (checksum >> 0) & 0xff; | |
1067 | buf[2] = (firmware->size >> 8) & 0xff; | |
1068 | buf[3] = (firmware->size >> 0) & 0xff; | |
1069 | ret = regmap_bulk_write(state->regmap, 0x50fc, buf, 4); | |
825b9670 | 1070 | if (ret) |
bf69e072 | 1071 | goto err_release_firmware; |
825b9670 | 1072 | |
96700d24 AP |
1073 | /* Download firmware */ |
1074 | #define LEN_MAX 16 | |
1075 | for (rem = firmware->size; rem > 0; rem -= LEN_MAX) { | |
1076 | len = min(LEN_MAX, rem); | |
f458a1bc | 1077 | ret = regmap_bulk_write(state->regmap, |
96700d24 AP |
1078 | 0x5100 + firmware->size - rem, |
1079 | &firmware->data[firmware->size - rem], | |
1080 | len); | |
825b9670 | 1081 | if (ret) { |
cbb2a299 AP |
1082 | dev_err(&client->dev, "firmware download failed %d\n", |
1083 | ret); | |
bf69e072 | 1084 | goto err_release_firmware; |
825b9670 AP |
1085 | } |
1086 | } | |
1087 | ||
96700d24 | 1088 | release_firmware(firmware); |
bf69e072 | 1089 | |
96700d24 | 1090 | /* Boot firmware */ |
f458a1bc | 1091 | ret = regmap_write(state->regmap, 0xe205, 0x01); |
825b9670 | 1092 | if (ret) |
bf69e072 | 1093 | goto err; |
825b9670 | 1094 | |
f458a1bc AP |
1095 | /* Check firmware status. 0c=OK, 04=fail */ |
1096 | ret = regmap_read_poll_timeout(state->regmap, 0x98be, utmp, | |
1097 | (utmp == 0x0c || utmp == 0x04), | |
1098 | 5000, 1000000); | |
1099 | if (ret) | |
bf69e072 | 1100 | goto err; |
825b9670 | 1101 | |
f458a1bc | 1102 | dev_dbg(&client->dev, "firmware status %02x\n", utmp); |
825b9670 | 1103 | |
f458a1bc | 1104 | if (utmp == 0x04) { |
f571e004 | 1105 | ret = -ENODEV; |
bf69e072 AP |
1106 | dev_err(&client->dev, "firmware did not run\n"); |
1107 | goto err; | |
f458a1bc | 1108 | } else if (utmp != 0x0c) { |
f571e004 | 1109 | ret = -ENODEV; |
bf69e072 AP |
1110 | dev_err(&client->dev, "firmware boot timeout\n"); |
1111 | goto err; | |
825b9670 AP |
1112 | } |
1113 | ||
bf69e072 AP |
1114 | dev_info(&client->dev, "found a '%s' in warm state\n", |
1115 | af9013_ops.info.name); | |
1116 | ||
1117 | return 0; | |
1118 | err_release_firmware: | |
96700d24 | 1119 | release_firmware(firmware); |
f571e004 | 1120 | err: |
bf69e072 | 1121 | dev_dbg(&client->dev, "failed %d\n", ret); |
825b9670 AP |
1122 | return ret; |
1123 | } | |
1124 | ||
bd336e63 | 1125 | static const struct dvb_frontend_ops af9013_ops = { |
59d3cc19 | 1126 | .delsys = { SYS_DVBT }, |
825b9670 | 1127 | .info = { |
f571e004 | 1128 | .name = "Afatech AF9013", |
f1b1eabf MCC |
1129 | .frequency_min_hz = 174 * MHz, |
1130 | .frequency_max_hz = 862 * MHz, | |
1131 | .frequency_stepsize_hz = 250 * kHz, | |
f571e004 AP |
1132 | .caps = FE_CAN_FEC_1_2 | |
1133 | FE_CAN_FEC_2_3 | | |
1134 | FE_CAN_FEC_3_4 | | |
1135 | FE_CAN_FEC_5_6 | | |
1136 | FE_CAN_FEC_7_8 | | |
1137 | FE_CAN_FEC_AUTO | | |
1138 | FE_CAN_QPSK | | |
1139 | FE_CAN_QAM_16 | | |
1140 | FE_CAN_QAM_64 | | |
1141 | FE_CAN_QAM_AUTO | | |
825b9670 AP |
1142 | FE_CAN_TRANSMISSION_MODE_AUTO | |
1143 | FE_CAN_GUARD_INTERVAL_AUTO | | |
1144 | FE_CAN_HIERARCHY_AUTO | | |
1145 | FE_CAN_RECOVER | | |
1146 | FE_CAN_MUTE_TS | |
1147 | }, | |
1148 | ||
825b9670 AP |
1149 | .init = af9013_init, |
1150 | .sleep = af9013_sleep, | |
825b9670 | 1151 | |
f571e004 | 1152 | .get_tune_settings = af9013_get_tune_settings, |
59d3cc19 MCC |
1153 | .set_frontend = af9013_set_frontend, |
1154 | .get_frontend = af9013_get_frontend, | |
825b9670 | 1155 | |
825b9670 | 1156 | .read_status = af9013_read_status, |
825b9670 | 1157 | .read_snr = af9013_read_snr, |
f571e004 AP |
1158 | .read_signal_strength = af9013_read_signal_strength, |
1159 | .read_ber = af9013_read_ber, | |
825b9670 | 1160 | .read_ucblocks = af9013_read_ucblocks, |
f571e004 | 1161 | }; |
825b9670 | 1162 | |
83d6b7c3 AP |
1163 | static int af9013_pid_filter_ctrl(struct dvb_frontend *fe, int onoff) |
1164 | { | |
1165 | struct af9013_state *state = fe->demodulator_priv; | |
1166 | struct i2c_client *client = state->client; | |
1167 | int ret; | |
1168 | ||
1169 | dev_dbg(&client->dev, "onoff %d\n", onoff); | |
1170 | ||
1171 | ret = regmap_update_bits(state->regmap, 0xd503, 0x01, onoff); | |
1172 | if (ret) | |
1173 | goto err; | |
1174 | ||
1175 | return 0; | |
1176 | err: | |
1177 | dev_dbg(&client->dev, "failed %d\n", ret); | |
1178 | return ret; | |
1179 | } | |
1180 | ||
1181 | static int af9013_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid, | |
1182 | int onoff) | |
1183 | { | |
1184 | struct af9013_state *state = fe->demodulator_priv; | |
1185 | struct i2c_client *client = state->client; | |
1186 | int ret; | |
1187 | u8 buf[2]; | |
1188 | ||
1189 | dev_dbg(&client->dev, "index %d, pid %04x, onoff %d\n", | |
1190 | index, pid, onoff); | |
1191 | ||
1192 | if (pid > 0x1fff) { | |
1193 | /* 0x2000 is kernel virtual pid for whole ts (all pids) */ | |
1194 | ret = 0; | |
1195 | goto err; | |
1196 | } | |
1197 | ||
1198 | buf[0] = (pid >> 0) & 0xff; | |
1199 | buf[1] = (pid >> 8) & 0xff; | |
1200 | ret = regmap_bulk_write(state->regmap, 0xd505, buf, 2); | |
1201 | if (ret) | |
1202 | goto err; | |
1203 | ret = regmap_write(state->regmap, 0xd504, onoff << 5 | index << 0); | |
1204 | if (ret) | |
1205 | goto err; | |
1206 | ||
1207 | return 0; | |
1208 | err: | |
1209 | dev_dbg(&client->dev, "failed %d\n", ret); | |
1210 | return ret; | |
1211 | } | |
1212 | ||
82d1ce3e AP |
1213 | static struct dvb_frontend *af9013_get_dvb_frontend(struct i2c_client *client) |
1214 | { | |
1215 | struct af9013_state *state = i2c_get_clientdata(client); | |
1216 | ||
1217 | dev_dbg(&client->dev, "\n"); | |
1218 | ||
1219 | return &state->fe; | |
1220 | } | |
1221 | ||
22e59e72 AP |
1222 | static struct i2c_adapter *af9013_get_i2c_adapter(struct i2c_client *client) |
1223 | { | |
1224 | struct af9013_state *state = i2c_get_clientdata(client); | |
1225 | ||
1226 | dev_dbg(&client->dev, "\n"); | |
1227 | ||
1228 | return state->muxc->adapter[0]; | |
1229 | } | |
1230 | ||
1231 | /* | |
1232 | * XXX: Hackish solution. We use virtual register, reg bit 16, to carry info | |
1233 | * about i2c adapter locking. Own locking is needed because i2c mux call has | |
1234 | * already locked i2c adapter. | |
1235 | */ | |
1236 | static int af9013_select(struct i2c_mux_core *muxc, u32 chan) | |
1237 | { | |
1238 | struct af9013_state *state = i2c_mux_priv(muxc); | |
1239 | struct i2c_client *client = state->client; | |
1240 | int ret; | |
1241 | ||
1242 | dev_dbg(&client->dev, "\n"); | |
1243 | ||
1244 | if (state->ts_mode == AF9013_TS_MODE_USB) | |
1245 | ret = regmap_update_bits(state->regmap, 0x1d417, 0x08, 0x08); | |
1246 | else | |
1247 | ret = regmap_update_bits(state->regmap, 0x1d607, 0x04, 0x04); | |
1248 | if (ret) | |
1249 | goto err; | |
1250 | ||
1251 | return 0; | |
1252 | err: | |
1253 | dev_dbg(&client->dev, "failed %d\n", ret); | |
1254 | return ret; | |
1255 | } | |
1256 | ||
1257 | static int af9013_deselect(struct i2c_mux_core *muxc, u32 chan) | |
1258 | { | |
1259 | struct af9013_state *state = i2c_mux_priv(muxc); | |
1260 | struct i2c_client *client = state->client; | |
1261 | int ret; | |
1262 | ||
1263 | dev_dbg(&client->dev, "\n"); | |
1264 | ||
1265 | if (state->ts_mode == AF9013_TS_MODE_USB) | |
1266 | ret = regmap_update_bits(state->regmap, 0x1d417, 0x08, 0x00); | |
1267 | else | |
1268 | ret = regmap_update_bits(state->regmap, 0x1d607, 0x04, 0x00); | |
1269 | if (ret) | |
1270 | goto err; | |
1271 | ||
1272 | return 0; | |
1273 | err: | |
1274 | dev_dbg(&client->dev, "failed %d\n", ret); | |
1275 | return ret; | |
1276 | } | |
1277 | ||
f458a1bc AP |
1278 | /* Own I2C access routines needed for regmap as chip uses extra command byte */ |
1279 | static int af9013_wregs(struct i2c_client *client, u8 cmd, u16 reg, | |
22e59e72 | 1280 | const u8 *val, int len, u8 lock) |
f458a1bc AP |
1281 | { |
1282 | int ret; | |
1283 | u8 buf[21]; | |
1284 | struct i2c_msg msg[1] = { | |
1285 | { | |
1286 | .addr = client->addr, | |
1287 | .flags = 0, | |
1288 | .len = 3 + len, | |
1289 | .buf = buf, | |
1290 | } | |
1291 | }; | |
1292 | ||
1293 | if (3 + len > sizeof(buf)) { | |
1294 | ret = -EINVAL; | |
1295 | goto err; | |
1296 | } | |
1297 | ||
1298 | buf[0] = (reg >> 8) & 0xff; | |
1299 | buf[1] = (reg >> 0) & 0xff; | |
1300 | buf[2] = cmd; | |
1301 | memcpy(&buf[3], val, len); | |
22e59e72 AP |
1302 | |
1303 | if (lock) | |
b1e1ca27 | 1304 | i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT); |
22e59e72 AP |
1305 | ret = __i2c_transfer(client->adapter, msg, 1); |
1306 | if (lock) | |
b1e1ca27 | 1307 | i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT); |
f458a1bc AP |
1308 | if (ret < 0) { |
1309 | goto err; | |
1310 | } else if (ret != 1) { | |
1311 | ret = -EREMOTEIO; | |
1312 | goto err; | |
1313 | } | |
1314 | ||
1315 | return 0; | |
1316 | err: | |
1317 | dev_dbg(&client->dev, "failed %d\n", ret); | |
1318 | return ret; | |
1319 | } | |
1320 | ||
1321 | static int af9013_rregs(struct i2c_client *client, u8 cmd, u16 reg, | |
22e59e72 | 1322 | u8 *val, int len, u8 lock) |
f458a1bc AP |
1323 | { |
1324 | int ret; | |
1325 | u8 buf[3]; | |
1326 | struct i2c_msg msg[2] = { | |
1327 | { | |
1328 | .addr = client->addr, | |
1329 | .flags = 0, | |
1330 | .len = 3, | |
1331 | .buf = buf, | |
1332 | }, { | |
1333 | .addr = client->addr, | |
1334 | .flags = I2C_M_RD, | |
1335 | .len = len, | |
1336 | .buf = val, | |
1337 | } | |
1338 | }; | |
1339 | ||
1340 | buf[0] = (reg >> 8) & 0xff; | |
1341 | buf[1] = (reg >> 0) & 0xff; | |
1342 | buf[2] = cmd; | |
22e59e72 AP |
1343 | |
1344 | if (lock) | |
b1e1ca27 | 1345 | i2c_lock_bus(client->adapter, I2C_LOCK_SEGMENT); |
22e59e72 AP |
1346 | ret = __i2c_transfer(client->adapter, msg, 2); |
1347 | if (lock) | |
b1e1ca27 | 1348 | i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT); |
f458a1bc AP |
1349 | if (ret < 0) { |
1350 | goto err; | |
1351 | } else if (ret != 2) { | |
1352 | ret = -EREMOTEIO; | |
1353 | goto err; | |
1354 | } | |
1355 | ||
1356 | return 0; | |
1357 | err: | |
1358 | dev_dbg(&client->dev, "failed %d\n", ret); | |
1359 | return ret; | |
1360 | } | |
1361 | ||
1362 | static int af9013_regmap_write(void *context, const void *data, size_t count) | |
1363 | { | |
1364 | struct i2c_client *client = context; | |
1365 | struct af9013_state *state = i2c_get_clientdata(client); | |
1366 | int ret, i; | |
1367 | u8 cmd; | |
22e59e72 AP |
1368 | u8 lock = !((u8 *)data)[0]; |
1369 | u16 reg = ((u8 *)data)[1] << 8 | ((u8 *)data)[2] << 0; | |
1370 | u8 *val = &((u8 *)data)[3]; | |
1371 | const unsigned int len = count - 3; | |
f458a1bc | 1372 | |
eaa455f0 | 1373 | if (state->ts_mode == AF9013_TS_MODE_USB && (reg & 0xff00) != 0xae00) { |
f458a1bc | 1374 | cmd = 0 << 7|0 << 6|(len - 1) << 2|1 << 1|1 << 0; |
22e59e72 | 1375 | ret = af9013_wregs(client, cmd, reg, val, len, lock); |
f458a1bc AP |
1376 | if (ret) |
1377 | goto err; | |
1378 | } else if (reg >= 0x5100 && reg < 0x8fff) { | |
1379 | /* Firmware download */ | |
1380 | cmd = 1 << 7|1 << 6|(len - 1) << 2|1 << 1|1 << 0; | |
22e59e72 | 1381 | ret = af9013_wregs(client, cmd, reg, val, len, lock); |
f458a1bc AP |
1382 | if (ret) |
1383 | goto err; | |
1384 | } else { | |
1385 | cmd = 0 << 7|0 << 6|(1 - 1) << 2|1 << 1|1 << 0; | |
1386 | for (i = 0; i < len; i++) { | |
22e59e72 AP |
1387 | ret = af9013_wregs(client, cmd, reg + i, val + i, 1, |
1388 | lock); | |
f458a1bc AP |
1389 | if (ret) |
1390 | goto err; | |
1391 | } | |
1392 | } | |
1393 | ||
1394 | return 0; | |
1395 | err: | |
1396 | dev_dbg(&client->dev, "failed %d\n", ret); | |
1397 | return ret; | |
1398 | } | |
1399 | ||
1400 | static int af9013_regmap_read(void *context, const void *reg_buf, | |
1401 | size_t reg_size, void *val_buf, size_t val_size) | |
1402 | { | |
1403 | struct i2c_client *client = context; | |
1404 | struct af9013_state *state = i2c_get_clientdata(client); | |
1405 | int ret, i; | |
1406 | u8 cmd; | |
22e59e72 AP |
1407 | u8 lock = !((u8 *)reg_buf)[0]; |
1408 | u16 reg = ((u8 *)reg_buf)[1] << 8 | ((u8 *)reg_buf)[2] << 0; | |
f458a1bc AP |
1409 | u8 *val = &((u8 *)val_buf)[0]; |
1410 | const unsigned int len = val_size; | |
1411 | ||
eaa455f0 | 1412 | if (state->ts_mode == AF9013_TS_MODE_USB && (reg & 0xff00) != 0xae00) { |
f458a1bc | 1413 | cmd = 0 << 7|0 << 6|(len - 1) << 2|1 << 1|0 << 0; |
22e59e72 | 1414 | ret = af9013_rregs(client, cmd, reg, val_buf, len, lock); |
f458a1bc AP |
1415 | if (ret) |
1416 | goto err; | |
1417 | } else { | |
1418 | cmd = 0 << 7|0 << 6|(1 - 1) << 2|1 << 1|0 << 0; | |
1419 | for (i = 0; i < len; i++) { | |
22e59e72 AP |
1420 | ret = af9013_rregs(client, cmd, reg + i, val + i, 1, |
1421 | lock); | |
f458a1bc AP |
1422 | if (ret) |
1423 | goto err; | |
1424 | } | |
1425 | } | |
1426 | ||
1427 | return 0; | |
1428 | err: | |
1429 | dev_dbg(&client->dev, "failed %d\n", ret); | |
1430 | return ret; | |
1431 | } | |
1432 | ||
82d1ce3e AP |
1433 | static int af9013_probe(struct i2c_client *client, |
1434 | const struct i2c_device_id *id) | |
1435 | { | |
1436 | struct af9013_state *state; | |
1437 | struct af9013_platform_data *pdata = client->dev.platform_data; | |
d029799b | 1438 | struct dtv_frontend_properties *c; |
82d1ce3e AP |
1439 | int ret, i; |
1440 | u8 firmware_version[4]; | |
f458a1bc AP |
1441 | static const struct regmap_bus regmap_bus = { |
1442 | .read = af9013_regmap_read, | |
1443 | .write = af9013_regmap_write, | |
1444 | }; | |
1445 | static const struct regmap_config regmap_config = { | |
22e59e72 AP |
1446 | /* Actual reg is 16 bits, see i2c adapter lock */ |
1447 | .reg_bits = 24, | |
1448 | .val_bits = 8, | |
f458a1bc | 1449 | }; |
82d1ce3e AP |
1450 | |
1451 | state = kzalloc(sizeof(*state), GFP_KERNEL); | |
1452 | if (!state) { | |
1453 | ret = -ENOMEM; | |
1454 | goto err; | |
1455 | } | |
1456 | ||
22e59e72 AP |
1457 | dev_dbg(&client->dev, "\n"); |
1458 | ||
82d1ce3e AP |
1459 | /* Setup the state */ |
1460 | state->client = client; | |
1461 | i2c_set_clientdata(client, state); | |
1462 | state->clk = pdata->clk; | |
1463 | state->tuner = pdata->tuner; | |
1464 | state->if_frequency = pdata->if_frequency; | |
1465 | state->ts_mode = pdata->ts_mode; | |
eaa455f0 | 1466 | state->ts_output_pin = pdata->ts_output_pin; |
82d1ce3e AP |
1467 | state->spec_inv = pdata->spec_inv; |
1468 | memcpy(&state->api_version, pdata->api_version, sizeof(state->api_version)); | |
1469 | memcpy(&state->gpio, pdata->gpio, sizeof(state->gpio)); | |
f458a1bc AP |
1470 | state->regmap = regmap_init(&client->dev, ®map_bus, client, |
1471 | ®map_config); | |
1472 | if (IS_ERR(state->regmap)) { | |
1473 | ret = PTR_ERR(state->regmap); | |
1474 | goto err_kfree; | |
1475 | } | |
22e59e72 AP |
1476 | /* Create mux i2c adapter */ |
1477 | state->muxc = i2c_mux_alloc(client->adapter, &client->dev, 1, 0, 0, | |
1478 | af9013_select, af9013_deselect); | |
1479 | if (!state->muxc) { | |
1480 | ret = -ENOMEM; | |
1481 | goto err_regmap_exit; | |
1482 | } | |
1483 | state->muxc->priv = state; | |
1484 | ret = i2c_mux_add_adapter(state->muxc, 0, 0, 0); | |
1485 | if (ret) | |
1486 | goto err_regmap_exit; | |
82d1ce3e AP |
1487 | |
1488 | /* Download firmware */ | |
eaa455f0 | 1489 | if (state->ts_mode != AF9013_TS_MODE_USB) { |
82d1ce3e AP |
1490 | ret = af9013_download_firmware(state); |
1491 | if (ret) | |
22e59e72 | 1492 | goto err_i2c_mux_del_adapters; |
82d1ce3e AP |
1493 | } |
1494 | ||
1495 | /* Firmware version */ | |
f458a1bc AP |
1496 | ret = regmap_bulk_read(state->regmap, 0x5103, firmware_version, |
1497 | sizeof(firmware_version)); | |
82d1ce3e | 1498 | if (ret) |
22e59e72 | 1499 | goto err_i2c_mux_del_adapters; |
82d1ce3e AP |
1500 | |
1501 | /* Set GPIOs */ | |
1502 | for (i = 0; i < sizeof(state->gpio); i++) { | |
1503 | ret = af9013_set_gpio(state, i, state->gpio[i]); | |
1504 | if (ret) | |
22e59e72 | 1505 | goto err_i2c_mux_del_adapters; |
82d1ce3e AP |
1506 | } |
1507 | ||
1508 | /* Create dvb frontend */ | |
1509 | memcpy(&state->fe.ops, &af9013_ops, sizeof(state->fe.ops)); | |
82d1ce3e AP |
1510 | state->fe.demodulator_priv = state; |
1511 | ||
1512 | /* Setup callbacks */ | |
1513 | pdata->get_dvb_frontend = af9013_get_dvb_frontend; | |
22e59e72 | 1514 | pdata->get_i2c_adapter = af9013_get_i2c_adapter; |
83d6b7c3 AP |
1515 | pdata->pid_filter = af9013_pid_filter; |
1516 | pdata->pid_filter_ctrl = af9013_pid_filter_ctrl; | |
82d1ce3e | 1517 | |
d029799b AP |
1518 | /* Init stats to indicate which stats are supported */ |
1519 | c = &state->fe.dtv_property_cache; | |
943a720f | 1520 | c->strength.len = 1; |
d029799b | 1521 | c->cnr.len = 1; |
233f3ef7 AP |
1522 | c->post_bit_error.len = 1; |
1523 | c->post_bit_count.len = 1; | |
1524 | c->block_error.len = 1; | |
1525 | c->block_count.len = 1; | |
d029799b | 1526 | |
82d1ce3e AP |
1527 | dev_info(&client->dev, "Afatech AF9013 successfully attached\n"); |
1528 | dev_info(&client->dev, "firmware version: %d.%d.%d.%d\n", | |
1529 | firmware_version[0], firmware_version[1], | |
1530 | firmware_version[2], firmware_version[3]); | |
1531 | return 0; | |
22e59e72 AP |
1532 | err_i2c_mux_del_adapters: |
1533 | i2c_mux_del_adapters(state->muxc); | |
f458a1bc AP |
1534 | err_regmap_exit: |
1535 | regmap_exit(state->regmap); | |
82d1ce3e AP |
1536 | err_kfree: |
1537 | kfree(state); | |
1538 | err: | |
1539 | dev_dbg(&client->dev, "failed %d\n", ret); | |
1540 | return ret; | |
1541 | } | |
1542 | ||
1543 | static int af9013_remove(struct i2c_client *client) | |
1544 | { | |
1545 | struct af9013_state *state = i2c_get_clientdata(client); | |
1546 | ||
1547 | dev_dbg(&client->dev, "\n"); | |
1548 | ||
22e59e72 AP |
1549 | i2c_mux_del_adapters(state->muxc); |
1550 | ||
f458a1bc AP |
1551 | regmap_exit(state->regmap); |
1552 | ||
82d1ce3e AP |
1553 | kfree(state); |
1554 | ||
1555 | return 0; | |
1556 | } | |
1557 | ||
1558 | static const struct i2c_device_id af9013_id_table[] = { | |
1559 | {"af9013", 0}, | |
1560 | {} | |
1561 | }; | |
1562 | MODULE_DEVICE_TABLE(i2c, af9013_id_table); | |
1563 | ||
1564 | static struct i2c_driver af9013_driver = { | |
1565 | .driver = { | |
1566 | .name = "af9013", | |
1567 | .suppress_bind_attrs = true, | |
1568 | }, | |
1569 | .probe = af9013_probe, | |
1570 | .remove = af9013_remove, | |
1571 | .id_table = af9013_id_table, | |
1572 | }; | |
1573 | ||
1574 | module_i2c_driver(af9013_driver); | |
1575 | ||
825b9670 AP |
1576 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); |
1577 | MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver"); | |
1578 | MODULE_LICENSE("GPL"); | |
a71103a6 | 1579 | MODULE_FIRMWARE(AF9013_FIRMWARE); |