1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver
5 * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
8 #include "si2157_priv.h"
10 static const struct dvb_tuner_ops si2157_ops
;
12 static int tuner_lock_debug
;
13 module_param(tuner_lock_debug
, int, 0644);
14 MODULE_PARM_DESC(tuner_lock_debug
, "if set, signal lock is briefly waited on after setting params");
16 /* execute firmware command */
17 static int si2157_cmd_execute(struct i2c_client
*client
, struct si2157_cmd
*cmd
)
19 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
21 unsigned long timeout
;
23 mutex_lock(&dev
->i2c_mutex
);
26 /* write cmd and args for firmware */
27 ret
= i2c_master_send(client
, cmd
->args
, cmd
->wlen
);
29 goto err_mutex_unlock
;
30 } else if (ret
!= cmd
->wlen
) {
32 goto err_mutex_unlock
;
37 /* wait cmd execution terminate */
39 timeout
= jiffies
+ msecs_to_jiffies(TIMEOUT
);
40 while (!time_after(jiffies
, timeout
)) {
41 ret
= i2c_master_recv(client
, cmd
->args
, cmd
->rlen
);
43 goto err_mutex_unlock
;
44 } else if (ret
!= cmd
->rlen
) {
46 goto err_mutex_unlock
;
50 if ((cmd
->args
[0] >> 7) & 0x01)
54 dev_dbg(&client
->dev
, "cmd execution took %d ms, status=%x\n",
55 jiffies_to_msecs(jiffies
) -
56 (jiffies_to_msecs(timeout
) - TIMEOUT
),
59 if (!((cmd
->args
[0] >> 7) & 0x01)) {
61 goto err_mutex_unlock
;
63 /* check error status bit */
64 if (cmd
->args
[0] & 0x40) {
66 goto err_mutex_unlock
;
70 mutex_unlock(&dev
->i2c_mutex
);
74 mutex_unlock(&dev
->i2c_mutex
);
75 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
79 static const struct si2157_tuner_info si2157_tuners
[] = {
80 { SI2141
, 0x60, false, SI2141_60_FIRMWARE
, SI2141_A10_FIRMWARE
},
81 { SI2141
, 0x61, false, SI2141_61_FIRMWARE
, SI2141_A10_FIRMWARE
},
82 { SI2146
, 0x11, false, SI2146_11_FIRMWARE
, NULL
},
83 { SI2147
, 0x50, false, SI2147_50_FIRMWARE
, NULL
},
84 { SI2148
, 0x32, true, SI2148_32_FIRMWARE
, SI2158_A20_FIRMWARE
},
85 { SI2148
, 0x33, true, SI2148_33_FIRMWARE
, SI2158_A20_FIRMWARE
},
86 { SI2157
, 0x50, false, SI2157_50_FIRMWARE
, SI2157_A30_FIRMWARE
},
87 { SI2158
, 0x50, false, SI2158_50_FIRMWARE
, SI2158_A20_FIRMWARE
},
88 { SI2158
, 0x51, false, SI2158_51_FIRMWARE
, SI2158_A20_FIRMWARE
},
89 { SI2177
, 0x50, false, SI2177_50_FIRMWARE
, SI2157_A30_FIRMWARE
},
92 static int si2157_load_firmware(struct dvb_frontend
*fe
,
95 struct i2c_client
*client
= fe
->tuner_priv
;
96 const struct firmware
*fw
;
97 int ret
, len
, remaining
;
98 struct si2157_cmd cmd
;
100 /* request the firmware, this will block and timeout */
101 ret
= firmware_request_nowarn(&fw
, fw_name
, &client
->dev
);
105 /* firmware should be n chunks of 17 bytes */
106 if (fw
->size
% 17 != 0) {
107 dev_err(&client
->dev
, "firmware file '%s' is invalid\n",
110 goto err_release_firmware
;
113 dev_info(&client
->dev
, "downloading firmware from file '%s'\n",
116 for (remaining
= fw
->size
; remaining
> 0; remaining
-= 17) {
117 len
= fw
->data
[fw
->size
- remaining
];
118 if (len
> SI2157_ARGLEN
) {
119 dev_err(&client
->dev
, "Bad firmware length\n");
121 goto err_release_firmware
;
123 memcpy(cmd
.args
, &fw
->data
[(fw
->size
- remaining
) + 1], len
);
126 ret
= si2157_cmd_execute(client
, &cmd
);
128 dev_err(&client
->dev
, "firmware download failed %d\n",
130 goto err_release_firmware
;
134 err_release_firmware
:
135 release_firmware(fw
);
140 static int si2157_find_and_load_firmware(struct dvb_frontend
*fe
)
142 struct i2c_client
*client
= fe
->tuner_priv
;
143 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
144 const char *fw_alt_name
= NULL
;
145 unsigned char part_id
, rom_id
;
146 const char *fw_name
= NULL
;
147 struct si2157_cmd cmd
;
148 bool required
= true;
151 if (dev
->dont_load_firmware
) {
152 dev_info(&client
->dev
,
153 "device is buggy, skipping firmware download\n");
157 /* query chip revision */
158 memcpy(cmd
.args
, "\x02", 1);
161 ret
= si2157_cmd_execute(client
, &cmd
);
165 part_id
= cmd
.args
[2];
166 rom_id
= cmd
.args
[12];
168 for (i
= 0; i
< ARRAY_SIZE(si2157_tuners
); i
++) {
169 if (si2157_tuners
[i
].part_id
!= part_id
)
171 required
= si2157_tuners
[i
].required
;
172 fw_alt_name
= si2157_tuners
[i
].fw_alt_name
;
174 /* Both part and rom ID match */
175 if (si2157_tuners
[i
].rom_id
== rom_id
) {
176 fw_name
= si2157_tuners
[i
].fw_name
;
181 if (required
&& !fw_name
&& !fw_alt_name
) {
182 dev_err(&client
->dev
,
183 "unknown chip version Si21%d-%c%c%c ROM 0x%02x\n",
184 part_id
, cmd
.args
[1], cmd
.args
[3], cmd
.args
[4], rom_id
);
188 /* Update the part id based on device's report */
189 dev
->part_id
= part_id
;
191 dev_info(&client
->dev
,
192 "found a 'Silicon Labs Si21%d-%c%c%c ROM 0x%02x'\n",
193 part_id
, cmd
.args
[1], cmd
.args
[3], cmd
.args
[4], rom_id
);
196 ret
= si2157_load_firmware(fe
, fw_name
);
200 /* Try alternate name, if any */
201 if (ret
== -ENOENT
&& fw_alt_name
)
202 ret
= si2157_load_firmware(fe
, fw_alt_name
);
204 if (ret
== -ENOENT
) {
206 dev_info(&client
->dev
, "Using ROM firmware.\n");
209 dev_err(&client
->dev
, "Can't continue without a firmware.\n");
210 } else if (ret
< 0) {
211 dev_err(&client
->dev
, "error %d when loading firmware\n", ret
);
216 static int si2157_init(struct dvb_frontend
*fe
)
218 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
219 struct i2c_client
*client
= fe
->tuner_priv
;
220 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
221 unsigned int xtal_trim
;
222 struct si2157_cmd cmd
;
225 dev_dbg(&client
->dev
, "\n");
227 /* Try to get Xtal trim property, to verify tuner still running */
228 memcpy(cmd
.args
, "\x15\x00\x02\x04", 4);
231 ret
= si2157_cmd_execute(client
, &cmd
);
233 xtal_trim
= cmd
.args
[2] | (cmd
.args
[3] << 8);
235 if (ret
== 0 && xtal_trim
< 16)
238 dev
->if_frequency
= 0; /* we no longer know current tuner state */
241 if (dev
->part_id
== SI2146
) {
242 /* clock_mode = XTAL, clock_freq = 24MHz */
243 memcpy(cmd
.args
, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
245 } else if (dev
->part_id
== SI2141
) {
246 /* clock_mode: XTAL, xout enabled */
247 memcpy(cmd
.args
, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
250 memcpy(cmd
.args
, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
254 ret
= si2157_cmd_execute(client
, &cmd
);
255 if (ret
&& (dev
->part_id
!= SI2141
|| ret
!= -EAGAIN
))
258 /* Si2141 needs a wake up command */
259 if (dev
->part_id
== SI2141
) {
260 memcpy(cmd
.args
, "\xc0\x08\x01\x02\x00\x00\x01", 7);
262 ret
= si2157_cmd_execute(client
, &cmd
);
267 /* Try to load the firmware */
268 ret
= si2157_find_and_load_firmware(fe
);
272 /* reboot the tuner with new firmware? */
273 memcpy(cmd
.args
, "\x01\x01", 2);
276 ret
= si2157_cmd_execute(client
, &cmd
);
280 /* query firmware version */
281 memcpy(cmd
.args
, "\x11", 1);
284 ret
= si2157_cmd_execute(client
, &cmd
);
288 dev_info(&client
->dev
, "firmware version: %c.%c.%d\n",
289 cmd
.args
[6], cmd
.args
[7], cmd
.args
[8]);
291 /* enable tuner status flags */
292 memcpy(cmd
.args
, "\x14\x00\x01\x05\x01\x00", 6);
295 ret
= si2157_cmd_execute(client
, &cmd
);
299 memcpy(cmd
.args
, "\x14\x00\x01\x06\x01\x00", 6);
302 ret
= si2157_cmd_execute(client
, &cmd
);
306 memcpy(cmd
.args
, "\x14\x00\x01\x07\x01\x00", 6);
309 ret
= si2157_cmd_execute(client
, &cmd
);
313 /* init statistics in order signal app which are supported */
315 c
->strength
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
316 /* start statistics polling */
317 schedule_delayed_work(&dev
->stat_work
, msecs_to_jiffies(1000));
323 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
327 static int si2157_sleep(struct dvb_frontend
*fe
)
329 struct i2c_client
*client
= fe
->tuner_priv
;
330 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
332 struct si2157_cmd cmd
;
334 dev_dbg(&client
->dev
, "\n");
338 /* stop statistics polling */
339 cancel_delayed_work_sync(&dev
->stat_work
);
342 memcpy(cmd
.args
, "\x16\x00", 2);
345 ret
= si2157_cmd_execute(client
, &cmd
);
351 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
355 static int si2157_tune_wait(struct i2c_client
*client
, u8 is_digital
)
357 #define TUN_TIMEOUT 40
358 #define DIG_TIMEOUT 30
359 #define ANALOG_TIMEOUT 150
360 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
362 unsigned long timeout
;
363 unsigned long start_time
;
368 tune_lock_mask
= 0x04;
370 tune_lock_mask
= 0x02;
372 mutex_lock(&dev
->i2c_mutex
);
374 /* wait tuner command complete */
375 start_time
= jiffies
;
376 timeout
= start_time
+ msecs_to_jiffies(TUN_TIMEOUT
);
378 ret
= i2c_master_recv(client
, &wait_status
,
379 sizeof(wait_status
));
381 goto err_mutex_unlock
;
382 } else if (ret
!= sizeof(wait_status
)) {
384 goto err_mutex_unlock
;
387 if (time_after(jiffies
, timeout
))
391 if ((wait_status
& 0x81) == 0x81)
393 usleep_range(5000, 10000);
396 dev_dbg(&client
->dev
, "tuning took %d ms, status=0x%x\n",
397 jiffies_to_msecs(jiffies
) - jiffies_to_msecs(start_time
),
400 /* if we tuned ok, wait a bit for tuner lock */
401 if (tuner_lock_debug
&& (wait_status
& 0x81) == 0x81) {
403 timeout
= jiffies
+ msecs_to_jiffies(DIG_TIMEOUT
);
405 timeout
= jiffies
+ msecs_to_jiffies(ANALOG_TIMEOUT
);
407 while (!time_after(jiffies
, timeout
)) {
408 ret
= i2c_master_recv(client
, &wait_status
,
409 sizeof(wait_status
));
411 goto err_mutex_unlock
;
412 } else if (ret
!= sizeof(wait_status
)) {
414 goto err_mutex_unlock
;
418 if (wait_status
& tune_lock_mask
)
420 usleep_range(5000, 10000);
423 dev_dbg(&client
->dev
, "tuning+lock took %d ms, status=0x%x\n",
424 jiffies_to_msecs(jiffies
) - jiffies_to_msecs(start_time
),
428 if ((wait_status
& 0xc0) != 0x80) {
430 goto err_mutex_unlock
;
433 mutex_unlock(&dev
->i2c_mutex
);
437 mutex_unlock(&dev
->i2c_mutex
);
438 dev_err(&client
->dev
, "failed=%d\n", ret
);
442 static int si2157_set_params(struct dvb_frontend
*fe
)
444 struct i2c_client
*client
= fe
->tuner_priv
;
445 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
446 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
448 struct si2157_cmd cmd
;
449 u8 bw
, delivery_system
;
451 u32 if_frequency
= 5000000;
453 dev_dbg(&client
->dev
,
454 "delivery_system=%d frequency=%u bandwidth_hz=%u\n",
455 c
->delivery_system
, c
->frequency
, c
->bandwidth_hz
);
462 if (SUPPORTS_1700KHz(dev
) && c
->bandwidth_hz
<= 1700000) {
465 } else if (c
->bandwidth_hz
<= 6000000) {
468 } else if (SUPPORTS_1700KHz(dev
) && c
->bandwidth_hz
<= 6100000) {
471 } else if (c
->bandwidth_hz
<= 7000000) {
479 switch (c
->delivery_system
) {
481 delivery_system
= 0x00;
482 if_frequency
= 3250000;
484 case SYS_DVBC_ANNEX_B
:
485 delivery_system
= 0x10;
486 if_frequency
= 4000000;
489 case SYS_DVBT2
: /* it seems DVB-T and DVB-T2 both are 0x20 here */
490 delivery_system
= 0x20;
492 case SYS_DVBC_ANNEX_A
:
493 case SYS_DVBC_ANNEX_C
:
494 delivery_system
= 0x30;
497 delivery_system
= 0x40;
500 delivery_system
= 0x60;
507 memcpy(cmd
.args
, "\x14\x00\x03\x07\x00\x00", 6);
508 cmd
.args
[4] = delivery_system
| bw
;
513 ret
= si2157_cmd_execute(client
, &cmd
);
517 /* On SI2146, set DTV AGC source to DLIF_AGC_3DB */
518 if (dev
->part_id
== SI2146
)
519 memcpy(cmd
.args
, "\x14\x00\x02\x07\x00\x01", 6);
521 memcpy(cmd
.args
, "\x14\x00\x02\x07\x00\x00", 6);
522 cmd
.args
[4] = dev
->if_port
;
525 ret
= si2157_cmd_execute(client
, &cmd
);
529 /* set digital if frequency if needed */
530 if (if_frequency
!= dev
->if_frequency
) {
531 memcpy(cmd
.args
, "\x14\x00\x06\x07", 4);
532 cmd
.args
[4] = (if_frequency
/ 1000) & 0xff;
533 cmd
.args
[5] = ((if_frequency
/ 1000) >> 8) & 0xff;
536 ret
= si2157_cmd_execute(client
, &cmd
);
540 dev
->if_frequency
= if_frequency
;
543 /* set digital frequency */
544 memcpy(cmd
.args
, "\x41\x00\x00\x00\x00\x00\x00\x00", 8);
545 cmd
.args
[4] = (c
->frequency
>> 0) & 0xff;
546 cmd
.args
[5] = (c
->frequency
>> 8) & 0xff;
547 cmd
.args
[6] = (c
->frequency
>> 16) & 0xff;
548 cmd
.args
[7] = (c
->frequency
>> 24) & 0xff;
551 ret
= si2157_cmd_execute(client
, &cmd
);
555 dev
->bandwidth
= bandwidth
;
556 dev
->frequency
= c
->frequency
;
558 si2157_tune_wait(client
, 1); /* wait to complete, ignore any errors */
564 dev
->if_frequency
= 0;
565 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
569 static int si2157_set_analog_params(struct dvb_frontend
*fe
,
570 struct analog_parameters
*params
)
572 struct i2c_client
*client
= fe
->tuner_priv
;
573 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
574 char *std
; /* for debugging */
576 struct si2157_cmd cmd
;
578 u32 if_frequency
= 0;
582 u8 color
= 0; /* 0=NTSC/PAL, 0x10=SECAM */
583 u8 invert_analog
= 1; /* analog tuner spectrum; 0=normal, 1=inverted */
585 if (!SUPPORTS_ATV_IF(dev
)) {
586 dev_info(&client
->dev
, "Analog tuning not supported yet for Si21%d\n",
599 if (params
->mode
== V4L2_TUNER_RADIO
) {
602 * bandwidth = 1700000; //best can do for FM, AGC will be a mess though
603 * if_frequency = 1250000; //HVR-225x(saa7164), HVR-12xx(cx23885)
604 * if_frequency = 6600000; //HVR-9xx(cx231xx)
605 * if_frequency = 5500000; //HVR-19xx(pvrusb2)
607 dev_err(&client
->dev
, "si2157 does not currently support FM radio\n");
611 tmp_lval
= params
->frequency
* 625LL;
612 do_div(tmp_lval
, 10); /* convert to HZ */
613 freq
= (u32
)tmp_lval
;
615 if (freq
< 1000000) /* is freq in KHz */
617 dev
->frequency
= freq
;
619 /* if_frequency values based on tda187271C2 */
620 if (params
->std
& (V4L2_STD_B
| V4L2_STD_GH
)) {
621 if (freq
>= 470000000) {
624 if_frequency
= 6000000;
627 (V4L2_STD_SECAM_G
| V4L2_STD_SECAM_H
)) {
634 if_frequency
= 6000000;
636 if (params
->std
& V4L2_STD_SECAM_B
) {
641 } else if (params
->std
& V4L2_STD_MN
) {
644 if_frequency
= 5400000;
646 } else if (params
->std
& V4L2_STD_PAL_I
) {
649 if_frequency
= 7250000; /* TODO: does not work yet */
651 } else if (params
->std
& V4L2_STD_DK
) {
654 if_frequency
= 6900000; /* TODO: does not work yet */
656 if (params
->std
& V4L2_STD_SECAM_DK
) {
660 } else if (params
->std
& V4L2_STD_SECAM_L
) {
663 if_frequency
= 6750000; /* TODO: untested */
666 } else if (params
->std
& V4L2_STD_SECAM_LC
) {
669 if_frequency
= 1250000; /* TODO: untested */
675 /* calc channel center freq */
676 freq
= freq
- 1250000 + (bandwidth
/ 2);
678 dev_dbg(&client
->dev
,
679 "mode=%d system=%u std='%s' params->frequency=%u center freq=%u if=%u bandwidth=%u\n",
680 params
->mode
, system
, std
, params
->frequency
,
681 freq
, if_frequency
, bandwidth
);
683 /* set analog IF port */
684 memcpy(cmd
.args
, "\x14\x00\x03\x06\x08\x02", 6);
685 /* in using dev->if_port, we assume analog and digital IF's */
686 /* are always on different ports */
687 /* assumes if_port definition is 0 or 1 for digital out */
688 cmd
.args
[4] = (dev
->if_port
== 1) ? 8 : 10;
689 /* Analog AGC assumed external */
690 cmd
.args
[5] = (dev
->if_port
== 1) ? 2 : 1;
693 ret
= si2157_cmd_execute(client
, &cmd
);
697 /* set analog IF output config */
698 memcpy(cmd
.args
, "\x14\x00\x0d\x06\x94\x64", 6);
701 ret
= si2157_cmd_execute(client
, &cmd
);
705 /* make this distinct from a digital IF */
706 dev
->if_frequency
= if_frequency
| 1;
708 /* calc and set tuner analog if center frequency */
709 if_frequency
= if_frequency
+ 1250000 - (bandwidth
/ 2);
710 dev_dbg(&client
->dev
, "IF Ctr freq=%d\n", if_frequency
);
712 memcpy(cmd
.args
, "\x14\x00\x0C\x06", 4);
713 cmd
.args
[4] = (if_frequency
/ 1000) & 0xff;
714 cmd
.args
[5] = ((if_frequency
/ 1000) >> 8) & 0xff;
717 ret
= si2157_cmd_execute(client
, &cmd
);
721 /* set analog AGC config */
722 memcpy(cmd
.args
, "\x14\x00\x07\x06\x32\xc8", 6);
725 ret
= si2157_cmd_execute(client
, &cmd
);
729 /* set analog video mode */
730 memcpy(cmd
.args
, "\x14\x00\x04\x06\x00\x00", 6);
731 cmd
.args
[4] = system
| color
;
732 /* can use dev->inversion if assumed applies to both digital/analog */
737 ret
= si2157_cmd_execute(client
, &cmd
);
741 /* set analog frequency */
742 memcpy(cmd
.args
, "\x41\x01\x00\x00\x00\x00\x00\x00", 8);
743 cmd
.args
[4] = (freq
>> 0) & 0xff;
744 cmd
.args
[5] = (freq
>> 8) & 0xff;
745 cmd
.args
[6] = (freq
>> 16) & 0xff;
746 cmd
.args
[7] = (freq
>> 24) & 0xff;
749 ret
= si2157_cmd_execute(client
, &cmd
);
753 dev
->bandwidth
= bandwidth
;
755 si2157_tune_wait(client
, 0); /* wait to complete, ignore any errors */
761 dev
->if_frequency
= 0;
762 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
766 static int si2157_get_frequency(struct dvb_frontend
*fe
, u32
*frequency
)
768 struct i2c_client
*client
= fe
->tuner_priv
;
769 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
771 *frequency
= dev
->frequency
;
772 dev_dbg(&client
->dev
, "freq=%u\n", dev
->frequency
);
776 static int si2157_get_bandwidth(struct dvb_frontend
*fe
, u32
*bandwidth
)
778 struct i2c_client
*client
= fe
->tuner_priv
;
779 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
781 *bandwidth
= dev
->bandwidth
;
782 dev_dbg(&client
->dev
, "bandwidth=%u\n", dev
->bandwidth
);
786 static int si2157_get_if_frequency(struct dvb_frontend
*fe
, u32
*frequency
)
788 struct i2c_client
*client
= fe
->tuner_priv
;
789 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
791 *frequency
= dev
->if_frequency
& ~1; /* strip analog IF indicator bit */
792 dev_dbg(&client
->dev
, "if_frequency=%u\n", *frequency
);
796 static int si2157_get_rf_strength(struct dvb_frontend
*fe
, u16
*rssi
)
798 struct i2c_client
*client
= fe
->tuner_priv
;
799 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
800 struct si2157_cmd cmd
;
804 dev_dbg(&client
->dev
, "\n");
806 memcpy(cmd
.args
, "\x42\x00", 2);
809 ret
= si2157_cmd_execute(client
, &cmd
);
813 c
->strength
.stat
[0].scale
= FE_SCALE_DECIBEL
;
814 c
->strength
.stat
[0].svalue
= (s8
)cmd
.args
[3] * 1000;
816 /* normalize values based on Silicon Labs reference
817 * add 100, then anything > 80 is 100% signal
819 strength
= (s8
)cmd
.args
[3] + 100;
820 strength
= clamp_val(strength
, 0, 80);
821 *rssi
= (u16
)(strength
* 0xffff / 80);
823 dev_dbg(&client
->dev
, "strength=%d rssi=%u\n",
824 (s8
)cmd
.args
[3], *rssi
);
828 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
832 static const struct dvb_tuner_ops si2157_ops
= {
834 .name
= "Silicon Labs Si2141/Si2146/2147/2148/2157/2158",
835 .frequency_min_hz
= 42 * MHz
,
836 .frequency_max_hz
= 870 * MHz
,
840 .sleep
= si2157_sleep
,
841 .set_params
= si2157_set_params
,
842 .set_analog_params
= si2157_set_analog_params
,
843 .get_frequency
= si2157_get_frequency
,
844 .get_bandwidth
= si2157_get_bandwidth
,
845 .get_if_frequency
= si2157_get_if_frequency
,
847 .get_rf_strength
= si2157_get_rf_strength
,
850 static void si2157_stat_work(struct work_struct
*work
)
852 struct si2157_dev
*dev
= container_of(work
, struct si2157_dev
, stat_work
.work
);
853 struct dvb_frontend
*fe
= dev
->fe
;
854 struct i2c_client
*client
= fe
->tuner_priv
;
855 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
856 struct si2157_cmd cmd
;
859 dev_dbg(&client
->dev
, "\n");
861 memcpy(cmd
.args
, "\x42\x00", 2);
864 ret
= si2157_cmd_execute(client
, &cmd
);
868 c
->strength
.stat
[0].scale
= FE_SCALE_DECIBEL
;
869 c
->strength
.stat
[0].svalue
= (s8
) cmd
.args
[3] * 1000;
871 schedule_delayed_work(&dev
->stat_work
, msecs_to_jiffies(2000));
874 c
->strength
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
875 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
878 static int si2157_probe(struct i2c_client
*client
)
880 const struct i2c_device_id
*id
= i2c_client_get_device_id(client
);
881 struct si2157_config
*cfg
= client
->dev
.platform_data
;
882 struct dvb_frontend
*fe
= cfg
->fe
;
883 struct si2157_dev
*dev
;
884 struct si2157_cmd cmd
;
887 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
890 dev_err(&client
->dev
, "kzalloc() failed\n");
894 i2c_set_clientdata(client
, dev
);
896 dev
->inversion
= cfg
->inversion
;
897 dev
->dont_load_firmware
= cfg
->dont_load_firmware
;
898 dev
->if_port
= cfg
->if_port
;
899 dev
->part_id
= (u8
)id
->driver_data
;
900 dev
->if_frequency
= 5000000; /* default value of property 0x0706 */
901 mutex_init(&dev
->i2c_mutex
);
902 INIT_DELAYED_WORK(&dev
->stat_work
, si2157_stat_work
);
904 /* check if the tuner is there */
907 ret
= si2157_cmd_execute(client
, &cmd
);
908 if (ret
&& ret
!= -EAGAIN
)
911 memcpy(&fe
->ops
.tuner_ops
, &si2157_ops
, sizeof(struct dvb_tuner_ops
));
912 fe
->tuner_priv
= client
;
914 #ifdef CONFIG_MEDIA_CONTROLLER
916 dev
->mdev
= cfg
->mdev
;
918 dev
->ent
.name
= KBUILD_MODNAME
;
919 dev
->ent
.function
= MEDIA_ENT_F_TUNER
;
921 dev
->pad
[SI2157_PAD_RF_INPUT
].flags
= MEDIA_PAD_FL_SINK
;
922 dev
->pad
[SI2157_PAD_RF_INPUT
].sig_type
= PAD_SIGNAL_ANALOG
;
923 dev
->pad
[SI2157_PAD_VID_OUT
].flags
= MEDIA_PAD_FL_SOURCE
;
924 dev
->pad
[SI2157_PAD_VID_OUT
].sig_type
= PAD_SIGNAL_ANALOG
;
925 dev
->pad
[SI2157_PAD_AUD_OUT
].flags
= MEDIA_PAD_FL_SOURCE
;
926 dev
->pad
[SI2157_PAD_AUD_OUT
].sig_type
= PAD_SIGNAL_AUDIO
;
928 ret
= media_entity_pads_init(&dev
->ent
, SI2157_NUM_PADS
,
934 ret
= media_device_register_entity(cfg
->mdev
, &dev
->ent
);
936 media_entity_cleanup(&dev
->ent
);
942 dev_info(&client
->dev
, "Silicon Labs Si21%d successfully attached\n",
950 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
954 static void si2157_remove(struct i2c_client
*client
)
956 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
957 struct dvb_frontend
*fe
= dev
->fe
;
959 dev_dbg(&client
->dev
, "\n");
961 /* stop statistics polling */
962 cancel_delayed_work_sync(&dev
->stat_work
);
964 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
966 media_device_unregister_entity(&dev
->ent
);
969 memset(&fe
->ops
.tuner_ops
, 0, sizeof(struct dvb_tuner_ops
));
970 fe
->tuner_priv
= NULL
;
975 * The part_id used here will only be used on buggy devices that don't
976 * accept firmware uploads. Non-buggy devices should just use "si2157" for
977 * all SiLabs TER tuners, as the driver should auto-detect it.
979 static const struct i2c_device_id si2157_id_table
[] = {
986 MODULE_DEVICE_TABLE(i2c
, si2157_id_table
);
988 static struct i2c_driver si2157_driver
= {
991 .suppress_bind_attrs
= true,
993 .probe
= si2157_probe
,
994 .remove
= si2157_remove
,
995 .id_table
= si2157_id_table
,
998 module_i2c_driver(si2157_driver
);
1000 MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon tuner driver");
1001 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1002 MODULE_LICENSE("GPL");
1003 MODULE_FIRMWARE(SI2158_A20_FIRMWARE
);
1004 MODULE_FIRMWARE(SI2141_A10_FIRMWARE
);
1005 MODULE_FIRMWARE(SI2157_A30_FIRMWARE
);
1006 MODULE_FIRMWARE(SI2141_60_FIRMWARE
);
1007 MODULE_FIRMWARE(SI2141_61_FIRMWARE
);
1008 MODULE_FIRMWARE(SI2146_11_FIRMWARE
);
1009 MODULE_FIRMWARE(SI2147_50_FIRMWARE
);
1010 MODULE_FIRMWARE(SI2148_32_FIRMWARE
);
1011 MODULE_FIRMWARE(SI2148_33_FIRMWARE
);
1012 MODULE_FIRMWARE(SI2157_50_FIRMWARE
);
1013 MODULE_FIRMWARE(SI2158_50_FIRMWARE
);
1014 MODULE_FIRMWARE(SI2158_51_FIRMWARE
);
1015 MODULE_FIRMWARE(SI2177_50_FIRMWARE
);