GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / staging / media / av7110 / sp8870.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3     Driver for Spase SP8870 demodulator
4
5     Copyright (C) 1999 Juergen Peitz
6
7
8 */
9 /*(DEBLOBBED)*/
10
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/device.h>
14 #include <linux/firmware.h>
15 #include <linux/delay.h>
16 #include <linux/string.h>
17 #include <linux/slab.h>
18
19 #include <media/dvb_frontend.h>
20 #include "sp8870.h"
21
22
23 struct sp8870_state {
24
25         struct i2c_adapter* i2c;
26
27         const struct sp8870_config* config;
28
29         struct dvb_frontend frontend;
30
31         /* demodulator private data */
32         u8 initialised:1;
33 };
34
35 static int debug;
36 #define dprintk(args...) \
37         do { \
38                 if (debug) printk(KERN_DEBUG "sp8870: " args); \
39         } while (0)
40
41 /* firmware size for sp8870 */
42 #define SP8870_FIRMWARE_SIZE 16382
43
44 /* starting point for firmware in file 'Sc_main.mc' */
45 #define SP8870_FIRMWARE_OFFSET 0x0A
46
47 static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
48 {
49         u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
50         struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
51         int err;
52
53         if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
54                 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
55                 return -EREMOTEIO;
56         }
57
58         return 0;
59 }
60
61 static int sp8870_readreg (struct sp8870_state* state, u16 reg)
62 {
63         int ret;
64         u8 b0 [] = { reg >> 8 , reg & 0xff };
65         u8 b1 [] = { 0, 0 };
66         struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
67                            { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
68
69         ret = i2c_transfer (state->i2c, msg, 2);
70
71         if (ret != 2) {
72                 dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
73                 return -1;
74         }
75
76         return (b1[0] << 8 | b1[1]);
77 }
78
79 static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
80 {
81         struct i2c_msg msg;
82         const char *fw_buf = fw->data;
83         int fw_pos;
84         u8 tx_buf[255];
85         int tx_len;
86         int err = 0;
87
88         dprintk ("%s: ...\n", __func__);
89
90         if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
91                 return -EINVAL;
92
93         // system controller stop
94         sp8870_writereg(state, 0x0F00, 0x0000);
95
96         // instruction RAM register hiword
97         sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF));
98
99         // instruction RAM MWR
100         sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16));
101
102         // do firmware upload
103         fw_pos = SP8870_FIRMWARE_OFFSET;
104         while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
105                 tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
106                 // write register 0xCF0A
107                 tx_buf[0] = 0xCF;
108                 tx_buf[1] = 0x0A;
109                 memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len);
110                 msg.addr = state->config->demod_address;
111                 msg.flags = 0;
112                 msg.buf = tx_buf;
113                 msg.len = tx_len + 2;
114                 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
115                         printk("%s: firmware upload failed!\n", __func__);
116                         printk ("%s: i2c error (err == %i)\n", __func__, err);
117                         return err;
118                 }
119                 fw_pos += tx_len;
120         }
121
122         dprintk ("%s: done!\n", __func__);
123         return 0;
124 };
125
126 static void sp8870_microcontroller_stop (struct sp8870_state* state)
127 {
128         sp8870_writereg(state, 0x0F08, 0x000);
129         sp8870_writereg(state, 0x0F09, 0x000);
130
131         // microcontroller STOP
132         sp8870_writereg(state, 0x0F00, 0x000);
133 }
134
135 static void sp8870_microcontroller_start (struct sp8870_state* state)
136 {
137         sp8870_writereg(state, 0x0F08, 0x000);
138         sp8870_writereg(state, 0x0F09, 0x000);
139
140         // microcontroller START
141         sp8870_writereg(state, 0x0F00, 0x001);
142         // not documented but if we don't read 0x0D01 out here
143         // we don't get a correct data valid signal
144         sp8870_readreg(state, 0x0D01);
145 }
146
147 static int sp8870_read_data_valid_signal(struct sp8870_state* state)
148 {
149         return (sp8870_readreg(state, 0x0D02) > 0);
150 }
151
152 static int configure_reg0xc05 (struct dtv_frontend_properties *p, u16 *reg0xc05)
153 {
154         int known_parameters = 1;
155
156         *reg0xc05 = 0x000;
157
158         switch (p->modulation) {
159         case QPSK:
160                 break;
161         case QAM_16:
162                 *reg0xc05 |= (1 << 10);
163                 break;
164         case QAM_64:
165                 *reg0xc05 |= (2 << 10);
166                 break;
167         case QAM_AUTO:
168                 known_parameters = 0;
169                 break;
170         default:
171                 return -EINVAL;
172         }
173
174         switch (p->hierarchy) {
175         case HIERARCHY_NONE:
176                 break;
177         case HIERARCHY_1:
178                 *reg0xc05 |= (1 << 7);
179                 break;
180         case HIERARCHY_2:
181                 *reg0xc05 |= (2 << 7);
182                 break;
183         case HIERARCHY_4:
184                 *reg0xc05 |= (3 << 7);
185                 break;
186         case HIERARCHY_AUTO:
187                 known_parameters = 0;
188                 break;
189         default:
190                 return -EINVAL;
191         }
192
193         switch (p->code_rate_HP) {
194         case FEC_1_2:
195                 break;
196         case FEC_2_3:
197                 *reg0xc05 |= (1 << 3);
198                 break;
199         case FEC_3_4:
200                 *reg0xc05 |= (2 << 3);
201                 break;
202         case FEC_5_6:
203                 *reg0xc05 |= (3 << 3);
204                 break;
205         case FEC_7_8:
206                 *reg0xc05 |= (4 << 3);
207                 break;
208         case FEC_AUTO:
209                 known_parameters = 0;
210                 break;
211         default:
212                 return -EINVAL;
213         }
214
215         if (known_parameters)
216                 *reg0xc05 |= (2 << 1);  /* use specified parameters */
217         else
218                 *reg0xc05 |= (1 << 1);  /* enable autoprobing */
219
220         return 0;
221 }
222
223 static int sp8870_wake_up(struct sp8870_state* state)
224 {
225         // enable TS output and interface pins
226         return sp8870_writereg(state, 0xC18, 0x00D);
227 }
228
229 static int sp8870_set_frontend_parameters(struct dvb_frontend *fe)
230 {
231         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
232         struct sp8870_state* state = fe->demodulator_priv;
233         int  err;
234         u16 reg0xc05;
235
236         if ((err = configure_reg0xc05(p, &reg0xc05)))
237                 return err;
238
239         // system controller stop
240         sp8870_microcontroller_stop(state);
241
242         // set tuner parameters
243         if (fe->ops.tuner_ops.set_params) {
244                 fe->ops.tuner_ops.set_params(fe);
245                 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
246         }
247
248         // sample rate correction bit [23..17]
249         sp8870_writereg(state, 0x0319, 0x000A);
250
251         // sample rate correction bit [16..0]
252         sp8870_writereg(state, 0x031A, 0x0AAB);
253
254         // integer carrier offset
255         sp8870_writereg(state, 0x0309, 0x0400);
256
257         // fractional carrier offset
258         sp8870_writereg(state, 0x030A, 0x0000);
259
260         // filter for 6/7/8 Mhz channel
261         if (p->bandwidth_hz == 6000000)
262                 sp8870_writereg(state, 0x0311, 0x0002);
263         else if (p->bandwidth_hz == 7000000)
264                 sp8870_writereg(state, 0x0311, 0x0001);
265         else
266                 sp8870_writereg(state, 0x0311, 0x0000);
267
268         // scan order: 2k first = 0x0000, 8k first = 0x0001
269         if (p->transmission_mode == TRANSMISSION_MODE_2K)
270                 sp8870_writereg(state, 0x0338, 0x0000);
271         else
272                 sp8870_writereg(state, 0x0338, 0x0001);
273
274         sp8870_writereg(state, 0xc05, reg0xc05);
275
276         // read status reg in order to clear pending irqs
277         err = sp8870_readreg(state, 0x200);
278         if (err < 0)
279                 return err;
280
281         // system controller start
282         sp8870_microcontroller_start(state);
283
284         return 0;
285 }
286
287 static int sp8870_init (struct dvb_frontend* fe)
288 {
289         struct sp8870_state* state = fe->demodulator_priv;
290         const struct firmware *fw = NULL;
291
292         sp8870_wake_up(state);
293         if (state->initialised) return 0;
294         state->initialised = 1;
295
296         dprintk ("%s\n", __func__);
297
298
299         /* request the firmware, this will block until someone uploads it */
300         printk("sp8870: waiting for firmware upload (%s)...\n", "/*(DEBLOBBED)*/");
301         if (state->config->request_firmware(fe, &fw, "/*(DEBLOBBED)*/")) {
302                 printk("sp8870: no firmware upload (timeout or file not found?)\n");
303                 return -EIO;
304         }
305
306         if (sp8870_firmware_upload(state, fw)) {
307                 printk("sp8870: writing firmware to device failed\n");
308                 release_firmware(fw);
309                 return -EIO;
310         }
311         release_firmware(fw);
312         printk("sp8870: firmware upload complete\n");
313
314         /* enable TS output and interface pins */
315         sp8870_writereg(state, 0xc18, 0x00d);
316
317         // system controller stop
318         sp8870_microcontroller_stop(state);
319
320         // ADC mode
321         sp8870_writereg(state, 0x0301, 0x0003);
322
323         // Reed Solomon parity bytes passed to output
324         sp8870_writereg(state, 0x0C13, 0x0001);
325
326         // MPEG clock is suppressed if no valid data
327         sp8870_writereg(state, 0x0C14, 0x0001);
328
329         /* bit 0x010: enable data valid signal */
330         sp8870_writereg(state, 0x0D00, 0x010);
331         sp8870_writereg(state, 0x0D01, 0x000);
332
333         return 0;
334 }
335
336 static int sp8870_read_status(struct dvb_frontend *fe,
337                               enum fe_status *fe_status)
338 {
339         struct sp8870_state* state = fe->demodulator_priv;
340         int status;
341         int signal;
342
343         *fe_status = 0;
344
345         status = sp8870_readreg (state, 0x0200);
346         if (status < 0)
347                 return -EIO;
348
349         signal = sp8870_readreg (state, 0x0303);
350         if (signal < 0)
351                 return -EIO;
352
353         if (signal > 0x0F)
354                 *fe_status |= FE_HAS_SIGNAL;
355         if (status & 0x08)
356                 *fe_status |= FE_HAS_SYNC;
357         if (status & 0x04)
358                 *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
359
360         return 0;
361 }
362
363 static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
364 {
365         struct sp8870_state* state = fe->demodulator_priv;
366         int ret;
367         u32 tmp;
368
369         *ber = 0;
370
371         ret = sp8870_readreg(state, 0xC08);
372         if (ret < 0)
373                 return -EIO;
374
375         tmp = ret & 0x3F;
376
377         ret = sp8870_readreg(state, 0xC07);
378         if (ret < 0)
379                 return -EIO;
380
381         tmp = ret << 6;
382         if (tmp >= 0x3FFF0)
383                 tmp = ~0;
384
385         *ber = tmp;
386
387         return 0;
388 }
389
390 static int sp8870_read_signal_strength(struct dvb_frontend* fe,  u16 * signal)
391 {
392         struct sp8870_state* state = fe->demodulator_priv;
393         int ret;
394         u16 tmp;
395
396         *signal = 0;
397
398         ret = sp8870_readreg (state, 0x306);
399         if (ret < 0)
400                 return -EIO;
401
402         tmp = ret << 8;
403
404         ret = sp8870_readreg (state, 0x303);
405         if (ret < 0)
406                 return -EIO;
407
408         tmp |= ret;
409
410         if (tmp)
411                 *signal = 0xFFFF - tmp;
412
413         return 0;
414 }
415
416 static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
417 {
418         struct sp8870_state* state = fe->demodulator_priv;
419         int ret;
420
421         *ublocks = 0;
422
423         ret = sp8870_readreg(state, 0xC0C);
424         if (ret < 0)
425                 return -EIO;
426
427         if (ret == 0xFFFF)
428                 ret = ~0;
429
430         *ublocks = ret;
431
432         return 0;
433 }
434
435 /* number of trials to recover from lockup */
436 #define MAXTRIALS 5
437 /* maximum checks for data valid signal */
438 #define MAXCHECKS 100
439
440 /* only for debugging: counter for detected lockups */
441 static int lockups;
442 /* only for debugging: counter for channel switches */
443 static int switches;
444
445 static int sp8870_set_frontend(struct dvb_frontend *fe)
446 {
447         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
448         struct sp8870_state* state = fe->demodulator_priv;
449
450         /*
451             The firmware of the sp8870 sometimes locks up after setting frontend parameters.
452             We try to detect this by checking the data valid signal.
453             If it is not set after MAXCHECKS we try to recover the lockup by setting
454             the frontend parameters again.
455         */
456
457         int err = 0;
458         int valid = 0;
459         int trials = 0;
460         int check_count = 0;
461
462         dprintk("%s: frequency = %i\n", __func__, p->frequency);
463
464         for (trials = 1; trials <= MAXTRIALS; trials++) {
465
466                 err = sp8870_set_frontend_parameters(fe);
467                 if (err)
468                         return err;
469
470                 for (check_count = 0; check_count < MAXCHECKS; check_count++) {
471 //                      valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
472                         valid = sp8870_read_data_valid_signal(state);
473                         if (valid) {
474                                 dprintk("%s: delay = %i usec\n",
475                                         __func__, check_count * 10);
476                                 break;
477                         }
478                         udelay(10);
479                 }
480                 if (valid)
481                         break;
482         }
483
484         if (!valid) {
485                 printk("%s: firmware crash!!!!!!\n", __func__);
486                 return -EIO;
487         }
488
489         if (debug) {
490                 if (valid) {
491                         if (trials > 1) {
492                                 printk("%s: firmware lockup!!!\n", __func__);
493                                 printk("%s: recovered after %i trial(s))\n",  __func__, trials - 1);
494                                 lockups++;
495                         }
496                 }
497                 switches++;
498                 printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
499         }
500
501         return 0;
502 }
503
504 static int sp8870_sleep(struct dvb_frontend* fe)
505 {
506         struct sp8870_state* state = fe->demodulator_priv;
507
508         // tristate TS output and disable interface pins
509         return sp8870_writereg(state, 0xC18, 0x000);
510 }
511
512 static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
513 {
514         fesettings->min_delay_ms = 350;
515         fesettings->step_size = 0;
516         fesettings->max_drift = 0;
517         return 0;
518 }
519
520 static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
521 {
522         struct sp8870_state* state = fe->demodulator_priv;
523
524         if (enable) {
525                 return sp8870_writereg(state, 0x206, 0x001);
526         } else {
527                 return sp8870_writereg(state, 0x206, 0x000);
528         }
529 }
530
531 static void sp8870_release(struct dvb_frontend* fe)
532 {
533         struct sp8870_state* state = fe->demodulator_priv;
534         kfree(state);
535 }
536
537 static const struct dvb_frontend_ops sp8870_ops;
538
539 struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
540                                    struct i2c_adapter* i2c)
541 {
542         struct sp8870_state* state = NULL;
543
544         /* allocate memory for the internal state */
545         state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
546         if (state == NULL) goto error;
547
548         /* setup the state */
549         state->config = config;
550         state->i2c = i2c;
551         state->initialised = 0;
552
553         /* check if the demod is there */
554         if (sp8870_readreg(state, 0x0200) < 0) goto error;
555
556         /* create dvb_frontend */
557         memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
558         state->frontend.demodulator_priv = state;
559         return &state->frontend;
560
561 error:
562         kfree(state);
563         return NULL;
564 }
565
566 static const struct dvb_frontend_ops sp8870_ops = {
567         .delsys = { SYS_DVBT },
568         .info = {
569                 .name                   = "Spase SP8870 DVB-T",
570                 .frequency_min_hz       = 470 * MHz,
571                 .frequency_max_hz       = 860 * MHz,
572                 .frequency_stepsize_hz  = 166666,
573                 .caps                   = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
574                                           FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
575                                           FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
576                                           FE_CAN_QPSK | FE_CAN_QAM_16 |
577                                           FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
578                                           FE_CAN_HIERARCHY_AUTO |  FE_CAN_RECOVER
579         },
580
581         .release = sp8870_release,
582
583         .init = sp8870_init,
584         .sleep = sp8870_sleep,
585         .i2c_gate_ctrl = sp8870_i2c_gate_ctrl,
586
587         .set_frontend = sp8870_set_frontend,
588         .get_tune_settings = sp8870_get_tune_settings,
589
590         .read_status = sp8870_read_status,
591         .read_ber = sp8870_read_ber,
592         .read_signal_strength = sp8870_read_signal_strength,
593         .read_ucblocks = sp8870_read_uncorrected_blocks,
594 };
595
596 module_param(debug, int, 0644);
597 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
598
599 MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
600 MODULE_AUTHOR("Juergen Peitz");
601 MODULE_LICENSE("GPL");
602
603 EXPORT_SYMBOL(sp8870_attach);