hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/dvb-frontends/si2168.c
....@@ -1,17 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Silicon Labs Si2168 DVB-T/T2/C demodulator driver
34 *
45 * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
156 */
167
178 #include <linux/delay.h>
....@@ -19,6 +10,13 @@
1910 #include "si2168_priv.h"
2011
2112 static const struct dvb_frontend_ops si2168_ops;
13
+
14
+static void cmd_init(struct si2168_cmd *cmd, const u8 *buf, int wlen, int rlen)
15
+{
16
+ memcpy(cmd->args, buf, wlen);
17
+ cmd->wlen = wlen;
18
+ cmd->rlen = rlen;
19
+}
2220
2321 /* execute firmware command */
2422 static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd *cmd)
....@@ -91,16 +89,23 @@
9189
9290 dev_dbg(&client->dev, "%s acquire: %d\n", __func__, acquire);
9391
92
+ /* set manual value */
93
+ if (dev->ts_mode & SI2168_TS_CLK_MANUAL) {
94
+ cmd_init(&cmd, "\x14\x00\x0d\x10\xe8\x03", 6, 4);
95
+ ret = si2168_cmd_execute(client, &cmd);
96
+ if (ret)
97
+ return ret;
98
+ }
9499 /* set TS_MODE property */
95
- memcpy(cmd.args, "\x14\x00\x01\x10\x10\x00", 6);
100
+ cmd_init(&cmd, "\x14\x00\x01\x10\x10\x00", 6, 4);
101
+ if (dev->ts_mode & SI2168_TS_CLK_MANUAL)
102
+ cmd.args[4] = SI2168_TS_CLK_MANUAL;
96103 if (acquire)
97104 cmd.args[4] |= dev->ts_mode;
98105 else
99106 cmd.args[4] |= SI2168_TS_TRISTATE;
100107 if (dev->ts_clock_gapped)
101108 cmd.args[4] |= 0x40;
102
- cmd.wlen = 6;
103
- cmd.rlen = 4;
104109 ret = si2168_cmd_execute(client, &cmd);
105110
106111 return ret;
....@@ -124,19 +129,13 @@
124129
125130 switch (c->delivery_system) {
126131 case SYS_DVBT:
127
- memcpy(cmd.args, "\xa0\x01", 2);
128
- cmd.wlen = 2;
129
- cmd.rlen = 13;
132
+ cmd_init(&cmd, "\xa0\x01", 2, 13);
130133 break;
131134 case SYS_DVBC_ANNEX_A:
132
- memcpy(cmd.args, "\x90\x01", 2);
133
- cmd.wlen = 2;
134
- cmd.rlen = 9;
135
+ cmd_init(&cmd, "\x90\x01", 2, 9);
135136 break;
136137 case SYS_DVBT2:
137
- memcpy(cmd.args, "\x50\x01", 2);
138
- cmd.wlen = 2;
139
- cmd.rlen = 14;
138
+ cmd_init(&cmd, "\x50\x01", 2, 14);
140139 break;
141140 default:
142141 ret = -EINVAL;
....@@ -173,9 +172,7 @@
173172
174173 /* BER */
175174 if (*status & FE_HAS_VITERBI) {
176
- memcpy(cmd.args, "\x82\x00", 2);
177
- cmd.wlen = 2;
178
- cmd.rlen = 3;
175
+ cmd_init(&cmd, "\x82\x00", 2, 3);
179176 ret = si2168_cmd_execute(client, &cmd);
180177 if (ret)
181178 goto err;
....@@ -206,9 +203,7 @@
206203
207204 /* UCB */
208205 if (*status & FE_HAS_SYNC) {
209
- memcpy(cmd.args, "\x84\x01", 2);
210
- cmd.wlen = 2;
211
- cmd.rlen = 3;
206
+ cmd_init(&cmd, "\x84\x01", 2, 3);
212207 ret = si2168_cmd_execute(client, &cmd);
213208 if (ret)
214209 goto err;
....@@ -294,22 +289,18 @@
294289 goto err;
295290 }
296291
297
- memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5);
298
- cmd.wlen = 5;
299
- cmd.rlen = 5;
292
+ cmd_init(&cmd, "\x88\x02\x02\x02\x02", 5, 5);
300293 ret = si2168_cmd_execute(client, &cmd);
301294 if (ret)
302295 goto err;
303296
304297 /* that has no big effect */
305298 if (c->delivery_system == SYS_DVBT)
306
- memcpy(cmd.args, "\x89\x21\x06\x11\xff\x98", 6);
299
+ cmd_init(&cmd, "\x89\x21\x06\x11\xff\x98", 6, 3);
307300 else if (c->delivery_system == SYS_DVBC_ANNEX_A)
308
- memcpy(cmd.args, "\x89\x21\x06\x11\x89\xf0", 6);
301
+ cmd_init(&cmd, "\x89\x21\x06\x11\x89\xf0", 6, 3);
309302 else if (c->delivery_system == SYS_DVBT2)
310
- memcpy(cmd.args, "\x89\x21\x06\x11\x89\x20", 6);
311
- cmd.wlen = 6;
312
- cmd.rlen = 3;
303
+ cmd_init(&cmd, "\x89\x21\x06\x11\x89\x20", 6, 3);
313304 ret = si2168_cmd_execute(client, &cmd);
314305 if (ret)
315306 goto err;
....@@ -326,103 +317,77 @@
326317 goto err;
327318 }
328319
329
- memcpy(cmd.args, "\x51\x03", 2);
330
- cmd.wlen = 2;
331
- cmd.rlen = 12;
320
+ cmd_init(&cmd, "\x51\x03", 2, 12);
332321 ret = si2168_cmd_execute(client, &cmd);
333322 if (ret)
334323 goto err;
335324
336
- memcpy(cmd.args, "\x12\x08\x04", 3);
337
- cmd.wlen = 3;
338
- cmd.rlen = 3;
325
+ cmd_init(&cmd, "\x12\x08\x04", 3, 3);
339326 ret = si2168_cmd_execute(client, &cmd);
340327 if (ret)
341328 goto err;
342329
343
- memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
344
- cmd.wlen = 6;
345
- cmd.rlen = 4;
330
+ cmd_init(&cmd, "\x14\x00\x0c\x10\x12\x00", 6, 4);
346331 ret = si2168_cmd_execute(client, &cmd);
347332 if (ret)
348333 goto err;
349334
350
- memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6);
351
- cmd.wlen = 6;
352
- cmd.rlen = 4;
335
+ cmd_init(&cmd, "\x14\x00\x06\x10\x24\x00", 6, 4);
353336 ret = si2168_cmd_execute(client, &cmd);
354337 if (ret)
355338 goto err;
356339
357
- memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
358
- cmd.wlen = 6;
359
- cmd.rlen = 4;
340
+ cmd_init(&cmd, "\x14\x00\x07\x10\x00\x24", 6, 4);
360341 ret = si2168_cmd_execute(client, &cmd);
361342 if (ret)
362343 goto err;
363344
364
- memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
345
+ cmd_init(&cmd, "\x14\x00\x0a\x10\x00\x00", 6, 4);
365346 cmd.args[4] = delivery_system | bandwidth;
366347 if (dev->spectral_inversion)
367348 cmd.args[5] |= 1;
368
- cmd.wlen = 6;
369
- cmd.rlen = 4;
370349 ret = si2168_cmd_execute(client, &cmd);
371350 if (ret)
372351 goto err;
373352
374353 /* set DVB-C symbol rate */
375354 if (c->delivery_system == SYS_DVBC_ANNEX_A) {
376
- memcpy(cmd.args, "\x14\x00\x02\x11", 4);
355
+ cmd_init(&cmd, "\x14\x00\x02\x11\x00\x00", 6, 4);
377356 cmd.args[4] = ((c->symbol_rate / 1000) >> 0) & 0xff;
378357 cmd.args[5] = ((c->symbol_rate / 1000) >> 8) & 0xff;
379
- cmd.wlen = 6;
380
- cmd.rlen = 4;
381358 ret = si2168_cmd_execute(client, &cmd);
382359 if (ret)
383360 goto err;
384361 }
385362
386
- memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
387
- cmd.wlen = 6;
388
- cmd.rlen = 4;
363
+ cmd_init(&cmd, "\x14\x00\x0f\x10\x10\x00", 6, 4);
389364 ret = si2168_cmd_execute(client, &cmd);
390365 if (ret)
391366 goto err;
392367
393
- memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x08", 6);
368
+ cmd_init(&cmd, "\x14\x00\x09\x10\xe3\x08", 6, 4);
394369 cmd.args[5] |= dev->ts_clock_inv ? 0x00 : 0x10;
395
- cmd.wlen = 6;
396
- cmd.rlen = 4;
397370 ret = si2168_cmd_execute(client, &cmd);
398371 if (ret)
399372 goto err;
400373
401
- memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x05", 6);
374
+ cmd_init(&cmd, "\x14\x00\x08\x10\xd7\x05", 6, 4);
402375 cmd.args[5] |= dev->ts_clock_inv ? 0x00 : 0x10;
403
- cmd.wlen = 6;
404
- cmd.rlen = 4;
405376 ret = si2168_cmd_execute(client, &cmd);
406377 if (ret)
407378 goto err;
408379
409
- memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
410
- cmd.wlen = 6;
411
- cmd.rlen = 4;
380
+ cmd_init(&cmd, "\x14\x00\x01\x12\x00\x00", 6, 4);
412381 ret = si2168_cmd_execute(client, &cmd);
413382 if (ret)
414383 goto err;
415384
416
- memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x00", 6);
417
- cmd.wlen = 6;
418
- cmd.rlen = 4;
385
+ cmd_init(&cmd, "\x14\x00\x01\x03\x0c\x00", 6, 4);
419386 ret = si2168_cmd_execute(client, &cmd);
420387 if (ret)
421388 goto err;
422389
423
- memcpy(cmd.args, "\x85", 1);
424
- cmd.wlen = 1;
425
- cmd.rlen = 1;
390
+ cmd_init(&cmd, "\x85", 1, 1);
426391 ret = si2168_cmd_execute(client, &cmd);
427392 if (ret)
428393 goto err;
....@@ -452,26 +417,21 @@
452417 dev_dbg(&client->dev, "\n");
453418
454419 /* initialize */
455
- memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
456
- cmd.wlen = 13;
457
- cmd.rlen = 0;
420
+ cmd_init(&cmd, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00",
421
+ 13, 0);
458422 ret = si2168_cmd_execute(client, &cmd);
459423 if (ret)
460424 goto err;
461425
462426 if (dev->warm) {
463427 /* resume */
464
- memcpy(cmd.args, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8);
465
- cmd.wlen = 8;
466
- cmd.rlen = 1;
428
+ cmd_init(&cmd, "\xc0\x06\x08\x0f\x00\x20\x21\x01", 8, 1);
467429 ret = si2168_cmd_execute(client, &cmd);
468430 if (ret)
469431 goto err;
470432
471433 udelay(100);
472
- memcpy(cmd.args, "\x85", 1);
473
- cmd.wlen = 1;
474
- cmd.rlen = 1;
434
+ cmd_init(&cmd, "\x85", 1, 1);
475435 ret = si2168_cmd_execute(client, &cmd);
476436 if (ret)
477437 goto err;
....@@ -480,9 +440,7 @@
480440 }
481441
482442 /* power up */
483
- memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
484
- cmd.wlen = 8;
485
- cmd.rlen = 1;
443
+ cmd_init(&cmd, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8, 1);
486444 ret = si2168_cmd_execute(client, &cmd);
487445 if (ret)
488446 goto err;
....@@ -520,9 +478,8 @@
520478 ret = -EINVAL;
521479 break;
522480 }
523
- memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
524
- cmd.wlen = len;
525
- cmd.rlen = 1;
481
+ cmd_init(&cmd, &fw->data[(fw->size - remaining) + 1],
482
+ len, 1);
526483 ret = si2168_cmd_execute(client, &cmd);
527484 if (ret)
528485 break;
....@@ -530,10 +487,7 @@
530487 } else if (fw->size % 8 == 0) {
531488 /* firmware is in the old format */
532489 for (remaining = fw->size; remaining > 0; remaining -= 8) {
533
- len = 8;
534
- memcpy(cmd.args, &fw->data[fw->size - remaining], len);
535
- cmd.wlen = len;
536
- cmd.rlen = 1;
490
+ cmd_init(&cmd, &fw->data[fw->size - remaining], 8, 1);
537491 ret = si2168_cmd_execute(client, &cmd);
538492 if (ret)
539493 break;
....@@ -550,17 +504,13 @@
550504
551505 release_firmware(fw);
552506
553
- memcpy(cmd.args, "\x01\x01", 2);
554
- cmd.wlen = 2;
555
- cmd.rlen = 1;
507
+ cmd_init(&cmd, "\x01\x01", 2, 1);
556508 ret = si2168_cmd_execute(client, &cmd);
557509 if (ret)
558510 goto err;
559511
560512 /* query firmware version */
561
- memcpy(cmd.args, "\x11", 1);
562
- cmd.wlen = 1;
563
- cmd.rlen = 10;
513
+ cmd_init(&cmd, "\x11", 1, 10);
564514 ret = si2168_cmd_execute(client, &cmd);
565515 if (ret)
566516 goto err;
....@@ -618,9 +568,7 @@
618568 if (dev->version > ('B' << 24 | 4 << 16 | 0 << 8 | 11 << 0))
619569 dev->warm = false;
620570
621
- memcpy(cmd.args, "\x13", 1);
622
- cmd.wlen = 1;
623
- cmd.rlen = 0;
571
+ cmd_init(&cmd, "\x13", 1, 0);
624572 ret = si2168_cmd_execute(client, &cmd);
625573 if (ret)
626574 goto err;
....@@ -646,9 +594,7 @@
646594 struct si2168_cmd cmd;
647595
648596 /* open I2C gate */
649
- memcpy(cmd.args, "\xc0\x0d\x01", 3);
650
- cmd.wlen = 3;
651
- cmd.rlen = 0;
597
+ cmd_init(&cmd, "\xc0\x0d\x01", 3, 0);
652598 ret = si2168_cmd_execute(client, &cmd);
653599 if (ret)
654600 goto err;
....@@ -666,9 +612,7 @@
666612 struct si2168_cmd cmd;
667613
668614 /* close I2C gate */
669
- memcpy(cmd.args, "\xc0\x0d\x00", 3);
670
- cmd.wlen = 3;
671
- cmd.rlen = 0;
615
+ cmd_init(&cmd, "\xc0\x0d\x00", 3, 0);
672616 ret = si2168_cmd_execute(client, &cmd);
673617 if (ret)
674618 goto err;
....@@ -683,8 +627,11 @@
683627 .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
684628 .info = {
685629 .name = "Silicon Labs Si2168",
686
- .symbol_rate_min = 1000000,
687
- .symbol_rate_max = 7200000,
630
+ .frequency_min_hz = 48 * MHz,
631
+ .frequency_max_hz = 870 * MHz,
632
+ .frequency_stepsize_hz = 62500,
633
+ .symbol_rate_min = 1000000,
634
+ .symbol_rate_max = 7200000,
688635 .caps = FE_CAN_FEC_1_2 |
689636 FE_CAN_FEC_2_3 |
690637 FE_CAN_FEC_3_4 |
....@@ -736,25 +683,20 @@
736683 mutex_init(&dev->i2c_mutex);
737684
738685 /* Initialize */
739
- memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
740
- cmd.wlen = 13;
741
- cmd.rlen = 0;
686
+ cmd_init(&cmd, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00",
687
+ 13, 0);
742688 ret = si2168_cmd_execute(client, &cmd);
743689 if (ret)
744690 goto err_kfree;
745691
746692 /* Power up */
747
- memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
748
- cmd.wlen = 8;
749
- cmd.rlen = 1;
693
+ cmd_init(&cmd, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8, 1);
750694 ret = si2168_cmd_execute(client, &cmd);
751695 if (ret)
752696 goto err_kfree;
753697
754698 /* Query chip revision */
755
- memcpy(cmd.args, "\x02", 1);
756
- cmd.wlen = 1;
757
- cmd.rlen = 13;
699
+ cmd_init(&cmd, "\x02", 1, 13);
758700 ret = si2168_cmd_execute(client, &cmd);
759701 if (ret)
760702 goto err_kfree;