1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Support for OR51211 (pcHDTV HD-2000) - VSB |
4 | * |
5 | * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> |
6 | * |
7 | * Based on code from Jack Kelliher (kelliher@xmission.com) |
8 | * Copyright (C) 2002 & pcHDTV, inc. |
9 | */ |
10 | |
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__ |
12 | |
13 | /* |
14 | * This driver needs external firmware. Please use the command |
15 | * "<kerneldir>/scripts/get_dvb_firmware or51211" to |
16 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware |
17 | * or /lib/firmware (depending on configuration of firmware hotplug). |
18 | */ |
19 | #define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" |
20 | |
21 | #include <linux/kernel.h> |
22 | #include <linux/module.h> |
23 | #include <linux/device.h> |
24 | #include <linux/firmware.h> |
25 | #include <linux/string.h> |
26 | #include <linux/slab.h> |
27 | #include <asm/byteorder.h> |
28 | |
29 | #include <linux/int_log.h> |
30 | #include <media/dvb_frontend.h> |
31 | #include "or51211.h" |
32 | |
33 | static int debug; |
34 | #define dprintk(args...) \ |
35 | do { if (debug) pr_debug(args); } while (0) |
36 | |
37 | static u8 run_buf[] = {0x7f,0x01}; |
38 | static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC |
39 | |
40 | struct or51211_state { |
41 | |
42 | struct i2c_adapter* i2c; |
43 | |
44 | /* Configuration settings */ |
45 | const struct or51211_config* config; |
46 | |
47 | struct dvb_frontend frontend; |
48 | struct bt878* bt; |
49 | |
50 | /* Demodulator private data */ |
51 | u8 initialized:1; |
52 | u32 snr; /* Result of last SNR calculation */ |
53 | |
54 | /* Tuner private data */ |
55 | u32 current_frequency; |
56 | }; |
57 | |
58 | static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf, |
59 | int len) |
60 | { |
61 | int err; |
62 | struct i2c_msg msg; |
63 | msg.addr = reg; |
64 | msg.flags = 0; |
65 | msg.len = len; |
66 | msg.buf = (u8 *)buf; |
67 | |
68 | if ((err = i2c_transfer (adap: state->i2c, msgs: &msg, num: 1)) != 1) { |
69 | pr_warn("error (addr %02x, err == %i)\n" , reg, err); |
70 | return -EREMOTEIO; |
71 | } |
72 | |
73 | return 0; |
74 | } |
75 | |
76 | static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len) |
77 | { |
78 | int err; |
79 | struct i2c_msg msg; |
80 | msg.addr = reg; |
81 | msg.flags = I2C_M_RD; |
82 | msg.len = len; |
83 | msg.buf = buf; |
84 | |
85 | if ((err = i2c_transfer (adap: state->i2c, msgs: &msg, num: 1)) != 1) { |
86 | pr_warn("error (addr %02x, err == %i)\n" , reg, err); |
87 | return -EREMOTEIO; |
88 | } |
89 | |
90 | return 0; |
91 | } |
92 | |
93 | static int or51211_load_firmware (struct dvb_frontend* fe, |
94 | const struct firmware *fw) |
95 | { |
96 | struct or51211_state* state = fe->demodulator_priv; |
97 | u8 tudata[585]; |
98 | int i; |
99 | |
100 | dprintk("Firmware is %zu bytes\n" , fw->size); |
101 | |
102 | /* Get eprom data */ |
103 | tudata[0] = 17; |
104 | if (i2c_writebytes(state,reg: 0x50,buf: tudata,len: 1)) { |
105 | pr_warn("error eprom addr\n" ); |
106 | return -1; |
107 | } |
108 | if (i2c_readbytes(state,reg: 0x50,buf: &tudata[145],len: 192)) { |
109 | pr_warn("error eprom\n" ); |
110 | return -1; |
111 | } |
112 | |
113 | /* Create firmware buffer */ |
114 | for (i = 0; i < 145; i++) |
115 | tudata[i] = fw->data[i]; |
116 | |
117 | for (i = 0; i < 248; i++) |
118 | tudata[i+337] = fw->data[145+i]; |
119 | |
120 | state->config->reset(fe); |
121 | |
122 | if (i2c_writebytes(state,reg: state->config->demod_address,buf: tudata,len: 585)) { |
123 | pr_warn("error 1\n" ); |
124 | return -1; |
125 | } |
126 | msleep(msecs: 1); |
127 | |
128 | if (i2c_writebytes(state,reg: state->config->demod_address, |
129 | buf: &fw->data[393],len: 8125)) { |
130 | pr_warn("error 2\n" ); |
131 | return -1; |
132 | } |
133 | msleep(msecs: 1); |
134 | |
135 | if (i2c_writebytes(state,reg: state->config->demod_address,buf: run_buf,len: 2)) { |
136 | pr_warn("error 3\n" ); |
137 | return -1; |
138 | } |
139 | |
140 | /* Wait at least 5 msec */ |
141 | msleep(msecs: 10); |
142 | if (i2c_writebytes(state,reg: state->config->demod_address,buf: run_buf,len: 2)) { |
143 | pr_warn("error 4\n" ); |
144 | return -1; |
145 | } |
146 | msleep(msecs: 10); |
147 | |
148 | pr_info("Done.\n" ); |
149 | return 0; |
150 | }; |
151 | |
152 | static int or51211_setmode(struct dvb_frontend* fe, int mode) |
153 | { |
154 | struct or51211_state* state = fe->demodulator_priv; |
155 | u8 rec_buf[14]; |
156 | |
157 | state->config->setmode(fe, mode); |
158 | |
159 | if (i2c_writebytes(state,reg: state->config->demod_address,buf: run_buf,len: 2)) { |
160 | pr_warn("error 1\n" ); |
161 | return -1; |
162 | } |
163 | |
164 | /* Wait at least 5 msec */ |
165 | msleep(msecs: 10); |
166 | if (i2c_writebytes(state,reg: state->config->demod_address,buf: run_buf,len: 2)) { |
167 | pr_warn("error 2\n" ); |
168 | return -1; |
169 | } |
170 | |
171 | msleep(msecs: 10); |
172 | |
173 | /* Set operation mode in Receiver 1 register; |
174 | * type 1: |
175 | * data 0x50h Automatic sets receiver channel conditions |
176 | * Automatic NTSC rejection filter |
177 | * Enable MPEG serial data output |
178 | * MPEG2tr |
179 | * High tuner phase noise |
180 | * normal +/-150kHz Carrier acquisition range |
181 | */ |
182 | if (i2c_writebytes(state,reg: state->config->demod_address,buf: cmd_buf,len: 3)) { |
183 | pr_warn("error 3\n" ); |
184 | return -1; |
185 | } |
186 | |
187 | rec_buf[0] = 0x04; |
188 | rec_buf[1] = 0x00; |
189 | rec_buf[2] = 0x03; |
190 | rec_buf[3] = 0x00; |
191 | msleep(msecs: 20); |
192 | if (i2c_writebytes(state,reg: state->config->demod_address,buf: rec_buf,len: 3)) { |
193 | pr_warn("error 5\n" ); |
194 | } |
195 | msleep(msecs: 3); |
196 | if (i2c_readbytes(state,reg: state->config->demod_address,buf: &rec_buf[10],len: 2)) { |
197 | pr_warn("error 6\n" ); |
198 | return -1; |
199 | } |
200 | dprintk("rec status %02x %02x\n" , rec_buf[10], rec_buf[11]); |
201 | |
202 | return 0; |
203 | } |
204 | |
205 | static int or51211_set_parameters(struct dvb_frontend *fe) |
206 | { |
207 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
208 | struct or51211_state* state = fe->demodulator_priv; |
209 | |
210 | /* Change only if we are actually changing the channel */ |
211 | if (state->current_frequency != p->frequency) { |
212 | if (fe->ops.tuner_ops.set_params) { |
213 | fe->ops.tuner_ops.set_params(fe); |
214 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); |
215 | } |
216 | |
217 | /* Set to ATSC mode */ |
218 | or51211_setmode(fe,mode: 0); |
219 | |
220 | /* Update current frequency */ |
221 | state->current_frequency = p->frequency; |
222 | } |
223 | return 0; |
224 | } |
225 | |
226 | static int or51211_read_status(struct dvb_frontend *fe, enum fe_status *status) |
227 | { |
228 | struct or51211_state* state = fe->demodulator_priv; |
229 | unsigned char rec_buf[2]; |
230 | unsigned char snd_buf[] = {0x04,0x00,0x03,0x00}; |
231 | *status = 0; |
232 | |
233 | /* Receiver Status */ |
234 | if (i2c_writebytes(state,reg: state->config->demod_address,buf: snd_buf,len: 3)) { |
235 | pr_warn("write error\n" ); |
236 | return -1; |
237 | } |
238 | msleep(msecs: 3); |
239 | if (i2c_readbytes(state,reg: state->config->demod_address,buf: rec_buf,len: 2)) { |
240 | pr_warn("read error\n" ); |
241 | return -1; |
242 | } |
243 | dprintk("%x %x\n" , rec_buf[0], rec_buf[1]); |
244 | |
245 | if (rec_buf[0] & 0x01) { /* Receiver Lock */ |
246 | *status |= FE_HAS_SIGNAL; |
247 | *status |= FE_HAS_CARRIER; |
248 | *status |= FE_HAS_VITERBI; |
249 | *status |= FE_HAS_SYNC; |
250 | *status |= FE_HAS_LOCK; |
251 | } |
252 | return 0; |
253 | } |
254 | |
255 | /* Calculate SNR estimation (scaled by 2^24) |
256 | |
257 | 8-VSB SNR equation from Oren datasheets |
258 | |
259 | For 8-VSB: |
260 | SNR[dB] = 10 * log10(219037.9454 / MSE^2 ) |
261 | |
262 | We re-write the snr equation as: |
263 | SNR * 2^24 = 10*(c - 2*intlog10(MSE)) |
264 | Where for 8-VSB, c = log10(219037.9454) * 2^24 */ |
265 | |
266 | static u32 calculate_snr(u32 mse, u32 c) |
267 | { |
268 | if (mse == 0) /* No signal */ |
269 | return 0; |
270 | |
271 | mse = 2*intlog10(value: mse); |
272 | if (mse > c) { |
273 | /* Negative SNR, which is possible, but realisticly the |
274 | demod will lose lock before the signal gets this bad. The |
275 | API only allows for unsigned values, so just return 0 */ |
276 | return 0; |
277 | } |
278 | return 10*(c - mse); |
279 | } |
280 | |
281 | static int or51211_read_snr(struct dvb_frontend* fe, u16* snr) |
282 | { |
283 | struct or51211_state* state = fe->demodulator_priv; |
284 | u8 rec_buf[2]; |
285 | u8 snd_buf[3]; |
286 | |
287 | /* SNR after Equalizer */ |
288 | snd_buf[0] = 0x04; |
289 | snd_buf[1] = 0x00; |
290 | snd_buf[2] = 0x04; |
291 | |
292 | if (i2c_writebytes(state,reg: state->config->demod_address,buf: snd_buf,len: 3)) { |
293 | pr_warn("error writing snr reg\n" ); |
294 | return -1; |
295 | } |
296 | if (i2c_readbytes(state,reg: state->config->demod_address,buf: rec_buf,len: 2)) { |
297 | pr_warn("read_status read error\n" ); |
298 | return -1; |
299 | } |
300 | |
301 | state->snr = calculate_snr(mse: rec_buf[0], c: 89599047); |
302 | *snr = (state->snr) >> 16; |
303 | |
304 | dprintk("noise = 0x%02x, snr = %d.%02d dB\n" , rec_buf[0], |
305 | state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); |
306 | |
307 | return 0; |
308 | } |
309 | |
310 | static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
311 | { |
312 | /* Calculate Strength from SNR up to 35dB */ |
313 | /* Even though the SNR can go higher than 35dB, there is some comfort */ |
314 | /* factor in having a range of strong signals that can show at 100% */ |
315 | struct or51211_state* state = (struct or51211_state*)fe->demodulator_priv; |
316 | u16 snr; |
317 | int ret; |
318 | |
319 | ret = fe->ops.read_snr(fe, &snr); |
320 | if (ret != 0) |
321 | return ret; |
322 | /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ |
323 | /* scale the range 0 - 35*2^24 into 0 - 65535 */ |
324 | if (state->snr >= 8960 * 0x10000) |
325 | *strength = 0xffff; |
326 | else |
327 | *strength = state->snr / 8960; |
328 | |
329 | return 0; |
330 | } |
331 | |
332 | static int or51211_read_ber(struct dvb_frontend* fe, u32* ber) |
333 | { |
334 | *ber = -ENOSYS; |
335 | return 0; |
336 | } |
337 | |
338 | static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
339 | { |
340 | *ucblocks = -ENOSYS; |
341 | return 0; |
342 | } |
343 | |
344 | static int or51211_sleep(struct dvb_frontend* fe) |
345 | { |
346 | return 0; |
347 | } |
348 | |
349 | static int or51211_init(struct dvb_frontend* fe) |
350 | { |
351 | struct or51211_state* state = fe->demodulator_priv; |
352 | const struct or51211_config* config = state->config; |
353 | const struct firmware* fw; |
354 | unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; |
355 | unsigned char rec_buf[14]; |
356 | int ret,i; |
357 | |
358 | if (!state->initialized) { |
359 | /* Request the firmware, this will block until it uploads */ |
360 | pr_info("Waiting for firmware upload (%s)...\n" , |
361 | OR51211_DEFAULT_FIRMWARE); |
362 | ret = config->request_firmware(fe, &fw, |
363 | OR51211_DEFAULT_FIRMWARE); |
364 | pr_info("Got Hotplug firmware\n" ); |
365 | if (ret) { |
366 | pr_warn("No firmware uploaded (timeout or file not found?)\n" ); |
367 | return ret; |
368 | } |
369 | |
370 | ret = or51211_load_firmware(fe, fw); |
371 | release_firmware(fw); |
372 | if (ret) { |
373 | pr_warn("Writing firmware to device failed!\n" ); |
374 | return ret; |
375 | } |
376 | pr_info("Firmware upload complete.\n" ); |
377 | |
378 | /* Set operation mode in Receiver 1 register; |
379 | * type 1: |
380 | * data 0x50h Automatic sets receiver channel conditions |
381 | * Automatic NTSC rejection filter |
382 | * Enable MPEG serial data output |
383 | * MPEG2tr |
384 | * High tuner phase noise |
385 | * normal +/-150kHz Carrier acquisition range |
386 | */ |
387 | if (i2c_writebytes(state,reg: state->config->demod_address, |
388 | buf: cmd_buf,len: 3)) { |
389 | pr_warn("Load DVR Error 5\n" ); |
390 | return -1; |
391 | } |
392 | |
393 | /* Read back ucode version to besure we loaded correctly */ |
394 | /* and are really up and running */ |
395 | rec_buf[0] = 0x04; |
396 | rec_buf[1] = 0x00; |
397 | rec_buf[2] = 0x03; |
398 | rec_buf[3] = 0x00; |
399 | msleep(msecs: 30); |
400 | if (i2c_writebytes(state,reg: state->config->demod_address, |
401 | buf: rec_buf,len: 3)) { |
402 | pr_warn("Load DVR Error A\n" ); |
403 | return -1; |
404 | } |
405 | msleep(msecs: 3); |
406 | if (i2c_readbytes(state,reg: state->config->demod_address, |
407 | buf: &rec_buf[10],len: 2)) { |
408 | pr_warn("Load DVR Error B\n" ); |
409 | return -1; |
410 | } |
411 | |
412 | rec_buf[0] = 0x04; |
413 | rec_buf[1] = 0x00; |
414 | rec_buf[2] = 0x01; |
415 | rec_buf[3] = 0x00; |
416 | msleep(msecs: 20); |
417 | if (i2c_writebytes(state,reg: state->config->demod_address, |
418 | buf: rec_buf,len: 3)) { |
419 | pr_warn("Load DVR Error C\n" ); |
420 | return -1; |
421 | } |
422 | msleep(msecs: 3); |
423 | if (i2c_readbytes(state,reg: state->config->demod_address, |
424 | buf: &rec_buf[12],len: 2)) { |
425 | pr_warn("Load DVR Error D\n" ); |
426 | return -1; |
427 | } |
428 | |
429 | for (i = 0; i < 8; i++) |
430 | rec_buf[i]=0xed; |
431 | |
432 | for (i = 0; i < 5; i++) { |
433 | msleep(msecs: 30); |
434 | get_ver_buf[4] = i+1; |
435 | if (i2c_writebytes(state,reg: state->config->demod_address, |
436 | buf: get_ver_buf,len: 5)) { |
437 | pr_warn("Load DVR Error 6 - %d\n" , i); |
438 | return -1; |
439 | } |
440 | msleep(msecs: 3); |
441 | |
442 | if (i2c_readbytes(state,reg: state->config->demod_address, |
443 | buf: &rec_buf[i*2],len: 2)) { |
444 | pr_warn("Load DVR Error 7 - %d\n" , i); |
445 | return -1; |
446 | } |
447 | /* If we didn't receive the right index, try again */ |
448 | if ((int)rec_buf[i*2+1]!=i+1){ |
449 | i--; |
450 | } |
451 | } |
452 | dprintk("read_fwbits %10ph\n" , rec_buf); |
453 | |
454 | pr_info("ver TU%02x%02x%02x VSB mode %02x Status %02x\n" , |
455 | rec_buf[2], rec_buf[4], rec_buf[6], rec_buf[12], |
456 | rec_buf[10]); |
457 | |
458 | rec_buf[0] = 0x04; |
459 | rec_buf[1] = 0x00; |
460 | rec_buf[2] = 0x03; |
461 | rec_buf[3] = 0x00; |
462 | msleep(msecs: 20); |
463 | if (i2c_writebytes(state,reg: state->config->demod_address, |
464 | buf: rec_buf,len: 3)) { |
465 | pr_warn("Load DVR Error 8\n" ); |
466 | return -1; |
467 | } |
468 | msleep(msecs: 20); |
469 | if (i2c_readbytes(state,reg: state->config->demod_address, |
470 | buf: &rec_buf[8],len: 2)) { |
471 | pr_warn("Load DVR Error 9\n" ); |
472 | return -1; |
473 | } |
474 | state->initialized = 1; |
475 | } |
476 | |
477 | return 0; |
478 | } |
479 | |
480 | static int or51211_get_tune_settings(struct dvb_frontend* fe, |
481 | struct dvb_frontend_tune_settings* fesettings) |
482 | { |
483 | fesettings->min_delay_ms = 500; |
484 | fesettings->step_size = 0; |
485 | fesettings->max_drift = 0; |
486 | return 0; |
487 | } |
488 | |
489 | static void or51211_release(struct dvb_frontend* fe) |
490 | { |
491 | struct or51211_state* state = fe->demodulator_priv; |
492 | state->config->sleep(fe); |
493 | kfree(objp: state); |
494 | } |
495 | |
496 | static const struct dvb_frontend_ops or51211_ops; |
497 | |
498 | struct dvb_frontend* or51211_attach(const struct or51211_config* config, |
499 | struct i2c_adapter* i2c) |
500 | { |
501 | struct or51211_state* state = NULL; |
502 | |
503 | /* Allocate memory for the internal state */ |
504 | state = kzalloc(size: sizeof(struct or51211_state), GFP_KERNEL); |
505 | if (state == NULL) |
506 | return NULL; |
507 | |
508 | /* Setup the state */ |
509 | state->config = config; |
510 | state->i2c = i2c; |
511 | state->initialized = 0; |
512 | state->current_frequency = 0; |
513 | |
514 | /* Create dvb_frontend */ |
515 | memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); |
516 | state->frontend.demodulator_priv = state; |
517 | return &state->frontend; |
518 | } |
519 | |
520 | static const struct dvb_frontend_ops or51211_ops = { |
521 | .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, |
522 | .info = { |
523 | .name = "Oren OR51211 VSB Frontend" , |
524 | .frequency_min_hz = 44 * MHz, |
525 | .frequency_max_hz = 958 * MHz, |
526 | .frequency_stepsize_hz = 166666, |
527 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
528 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
529 | FE_CAN_8VSB |
530 | }, |
531 | |
532 | .release = or51211_release, |
533 | |
534 | .init = or51211_init, |
535 | .sleep = or51211_sleep, |
536 | |
537 | .set_frontend = or51211_set_parameters, |
538 | .get_tune_settings = or51211_get_tune_settings, |
539 | |
540 | .read_status = or51211_read_status, |
541 | .read_ber = or51211_read_ber, |
542 | .read_signal_strength = or51211_read_signal_strength, |
543 | .read_snr = or51211_read_snr, |
544 | .read_ucblocks = or51211_read_ucblocks, |
545 | }; |
546 | |
547 | module_param(debug, int, 0644); |
548 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)." ); |
549 | |
550 | MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver" ); |
551 | MODULE_AUTHOR("Kirk Lapray" ); |
552 | MODULE_LICENSE("GPL" ); |
553 | |
554 | EXPORT_SYMBOL_GPL(or51211_attach); |
555 | |
556 | |