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 int si2157_init(struct dvb_frontend
*fe
)
81 struct i2c_client
*client
= fe
->tuner_priv
;
82 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
83 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
84 int ret
, len
, remaining
;
85 struct si2157_cmd cmd
;
86 const struct firmware
*fw
;
88 unsigned int chip_id
, xtal_trim
;
90 dev_dbg(&client
->dev
, "\n");
92 /* Try to get Xtal trim property, to verify tuner still running */
93 memcpy(cmd
.args
, "\x15\x00\x04\x02", 4);
96 ret
= si2157_cmd_execute(client
, &cmd
);
98 xtal_trim
= cmd
.args
[2] | (cmd
.args
[3] << 8);
100 if (ret
== 0 && xtal_trim
< 16)
103 dev
->if_frequency
= 0; /* we no longer know current tuner state */
106 if (dev
->chiptype
== SI2157_CHIPTYPE_SI2146
) {
107 memcpy(cmd
.args
, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
109 } else if (dev
->chiptype
== SI2157_CHIPTYPE_SI2141
) {
110 memcpy(cmd
.args
, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
113 memcpy(cmd
.args
, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
117 ret
= si2157_cmd_execute(client
, &cmd
);
118 if (ret
&& (dev
->chiptype
!= SI2157_CHIPTYPE_SI2141
|| ret
!= -EAGAIN
))
121 /* Si2141 needs a second command before it answers the revision query */
122 if (dev
->chiptype
== SI2157_CHIPTYPE_SI2141
) {
123 memcpy(cmd
.args
, "\xc0\x08\x01\x02\x00\x00\x01", 7);
125 ret
= si2157_cmd_execute(client
, &cmd
);
130 if (dev
->dont_load_firmware
) {
131 dev_info(&client
->dev
, "device is buggy, skipping firmware download\n");
132 goto skip_fw_download
;
135 /* query chip revision */
136 memcpy(cmd
.args
, "\x02", 1);
139 ret
= si2157_cmd_execute(client
, &cmd
);
143 chip_id
= cmd
.args
[1] << 24 | cmd
.args
[2] << 16 | cmd
.args
[3] << 8 |
146 #define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
147 #define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
148 #define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
149 #define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
150 #define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
151 #define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
152 #define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
157 fw_name
= SI2158_A20_FIRMWARE
;
160 fw_name
= SI2141_A10_FIRMWARE
;
163 fw_name
= SI2157_A30_FIRMWARE
;
171 dev_err(&client
->dev
, "unknown chip version Si21%d-%c%c%c\n",
172 cmd
.args
[2], cmd
.args
[1],
173 cmd
.args
[3], cmd
.args
[4]);
178 dev_info(&client
->dev
, "found a 'Silicon Labs Si21%d-%c%c%c'\n",
179 cmd
.args
[2], cmd
.args
[1], cmd
.args
[3], cmd
.args
[4]);
182 goto skip_fw_download
;
184 /* request the firmware, this will block and timeout */
185 ret
= request_firmware(&fw
, fw_name
, &client
->dev
);
187 dev_err(&client
->dev
, "firmware file '%s' not found\n",
192 /* firmware should be n chunks of 17 bytes */
193 if (fw
->size
% 17 != 0) {
194 dev_err(&client
->dev
, "firmware file '%s' is invalid\n",
197 goto err_release_firmware
;
200 dev_info(&client
->dev
, "downloading firmware from file '%s'\n",
203 for (remaining
= fw
->size
; remaining
> 0; remaining
-= 17) {
204 len
= fw
->data
[fw
->size
- remaining
];
205 if (len
> SI2157_ARGLEN
) {
206 dev_err(&client
->dev
, "Bad firmware length\n");
208 goto err_release_firmware
;
210 memcpy(cmd
.args
, &fw
->data
[(fw
->size
- remaining
) + 1], len
);
213 ret
= si2157_cmd_execute(client
, &cmd
);
215 dev_err(&client
->dev
, "firmware download failed %d\n",
217 goto err_release_firmware
;
221 release_firmware(fw
);
224 /* reboot the tuner with new firmware? */
225 memcpy(cmd
.args
, "\x01\x01", 2);
228 ret
= si2157_cmd_execute(client
, &cmd
);
232 /* query firmware version */
233 memcpy(cmd
.args
, "\x11", 1);
236 ret
= si2157_cmd_execute(client
, &cmd
);
240 dev_info(&client
->dev
, "firmware version: %c.%c.%d\n",
241 cmd
.args
[6], cmd
.args
[7], cmd
.args
[8]);
243 /* enable tuner status flags */
244 memcpy(cmd
.args
, "\x14\x00\x01\x05\x01\x00", 6);
247 ret
= si2157_cmd_execute(client
, &cmd
);
251 memcpy(cmd
.args
, "\x14\x00\x01\x06\x01\x00", 6);
254 ret
= si2157_cmd_execute(client
, &cmd
);
258 memcpy(cmd
.args
, "\x14\x00\x01\x07\x01\x00", 6);
261 ret
= si2157_cmd_execute(client
, &cmd
);
265 /* init statistics in order signal app which are supported */
267 c
->strength
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
268 /* start statistics polling */
269 schedule_delayed_work(&dev
->stat_work
, msecs_to_jiffies(1000));
273 err_release_firmware
:
274 release_firmware(fw
);
276 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
280 static int si2157_sleep(struct dvb_frontend
*fe
)
282 struct i2c_client
*client
= fe
->tuner_priv
;
283 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
285 struct si2157_cmd cmd
;
287 dev_dbg(&client
->dev
, "\n");
291 /* stop statistics polling */
292 cancel_delayed_work_sync(&dev
->stat_work
);
295 memcpy(cmd
.args
, "\x16\x00", 2);
298 ret
= si2157_cmd_execute(client
, &cmd
);
304 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
308 static int si2157_tune_wait(struct i2c_client
*client
, u8 is_digital
)
310 #define TUN_TIMEOUT 40
311 #define DIG_TIMEOUT 30
312 #define ANALOG_TIMEOUT 150
313 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
315 unsigned long timeout
;
316 unsigned long start_time
;
321 tune_lock_mask
= 0x04;
323 tune_lock_mask
= 0x02;
325 mutex_lock(&dev
->i2c_mutex
);
327 /* wait tuner command complete */
328 start_time
= jiffies
;
329 timeout
= start_time
+ msecs_to_jiffies(TUN_TIMEOUT
);
331 ret
= i2c_master_recv(client
, &wait_status
,
332 sizeof(wait_status
));
334 goto err_mutex_unlock
;
335 } else if (ret
!= sizeof(wait_status
)) {
337 goto err_mutex_unlock
;
340 if (time_after(jiffies
, timeout
))
344 if ((wait_status
& 0x81) == 0x81)
346 usleep_range(5000, 10000);
349 dev_dbg(&client
->dev
, "tuning took %d ms, status=0x%x\n",
350 jiffies_to_msecs(jiffies
) - jiffies_to_msecs(start_time
),
353 /* if we tuned ok, wait a bit for tuner lock */
354 if (tuner_lock_debug
&& (wait_status
& 0x81) == 0x81) {
356 timeout
= jiffies
+ msecs_to_jiffies(DIG_TIMEOUT
);
358 timeout
= jiffies
+ msecs_to_jiffies(ANALOG_TIMEOUT
);
360 while (!time_after(jiffies
, timeout
)) {
361 ret
= i2c_master_recv(client
, &wait_status
,
362 sizeof(wait_status
));
364 goto err_mutex_unlock
;
365 } else if (ret
!= sizeof(wait_status
)) {
367 goto err_mutex_unlock
;
371 if (wait_status
& tune_lock_mask
)
373 usleep_range(5000, 10000);
376 dev_dbg(&client
->dev
, "tuning+lock took %d ms, status=0x%x\n",
377 jiffies_to_msecs(jiffies
) - jiffies_to_msecs(start_time
),
381 if ((wait_status
& 0xc0) != 0x80) {
383 goto err_mutex_unlock
;
386 mutex_unlock(&dev
->i2c_mutex
);
390 mutex_unlock(&dev
->i2c_mutex
);
391 dev_err(&client
->dev
, "failed=%d\n", ret
);
395 static int si2157_set_params(struct dvb_frontend
*fe
)
397 struct i2c_client
*client
= fe
->tuner_priv
;
398 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
399 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
401 struct si2157_cmd cmd
;
402 u8 bandwidth
, delivery_system
;
403 u32 if_frequency
= 5000000;
405 dev_dbg(&client
->dev
,
406 "delivery_system=%d frequency=%u bandwidth_hz=%u\n",
407 c
->delivery_system
, c
->frequency
, c
->bandwidth_hz
);
414 if (c
->bandwidth_hz
<= 6000000)
416 else if (c
->bandwidth_hz
<= 7000000)
418 else if (c
->bandwidth_hz
<= 8000000)
423 switch (c
->delivery_system
) {
425 delivery_system
= 0x00;
426 if_frequency
= 3250000;
428 case SYS_DVBC_ANNEX_B
:
429 delivery_system
= 0x10;
430 if_frequency
= 4000000;
433 case SYS_DVBT2
: /* it seems DVB-T and DVB-T2 both are 0x20 here */
434 delivery_system
= 0x20;
436 case SYS_DVBC_ANNEX_A
:
437 delivery_system
= 0x30;
444 memcpy(cmd
.args
, "\x14\x00\x03\x07\x00\x00", 6);
445 cmd
.args
[4] = delivery_system
| bandwidth
;
450 ret
= si2157_cmd_execute(client
, &cmd
);
454 if (dev
->chiptype
== SI2157_CHIPTYPE_SI2146
)
455 memcpy(cmd
.args
, "\x14\x00\x02\x07\x00\x01", 6);
457 memcpy(cmd
.args
, "\x14\x00\x02\x07\x00\x00", 6);
458 cmd
.args
[4] = dev
->if_port
;
461 ret
= si2157_cmd_execute(client
, &cmd
);
465 /* set digital if frequency if needed */
466 if (if_frequency
!= dev
->if_frequency
) {
467 memcpy(cmd
.args
, "\x14\x00\x06\x07", 4);
468 cmd
.args
[4] = (if_frequency
/ 1000) & 0xff;
469 cmd
.args
[5] = ((if_frequency
/ 1000) >> 8) & 0xff;
472 ret
= si2157_cmd_execute(client
, &cmd
);
476 dev
->if_frequency
= if_frequency
;
479 /* set digital frequency */
480 memcpy(cmd
.args
, "\x41\x00\x00\x00\x00\x00\x00\x00", 8);
481 cmd
.args
[4] = (c
->frequency
>> 0) & 0xff;
482 cmd
.args
[5] = (c
->frequency
>> 8) & 0xff;
483 cmd
.args
[6] = (c
->frequency
>> 16) & 0xff;
484 cmd
.args
[7] = (c
->frequency
>> 24) & 0xff;
487 ret
= si2157_cmd_execute(client
, &cmd
);
491 dev
->bandwidth
= bandwidth
;
492 dev
->frequency
= c
->frequency
;
494 si2157_tune_wait(client
, 1); /* wait to complete, ignore any errors */
500 dev
->if_frequency
= 0;
501 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
505 static int si2157_set_analog_params(struct dvb_frontend
*fe
,
506 struct analog_parameters
*params
)
508 struct i2c_client
*client
= fe
->tuner_priv
;
509 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
510 char *std
; /* for debugging */
512 struct si2157_cmd cmd
;
514 u32 if_frequency
= 0;
518 u8 color
= 0; /* 0=NTSC/PAL, 0x10=SECAM */
519 u8 invert_analog
= 1; /* analog tuner spectrum; 0=normal, 1=inverted */
521 if (dev
->chiptype
!= SI2157_CHIPTYPE_SI2157
) {
522 dev_info(&client
->dev
, "Analog tuning not supported for chiptype=%u\n",
535 if (params
->mode
== V4L2_TUNER_RADIO
) {
538 * bandwidth = 1700000; //best can do for FM, AGC will be a mess though
539 * if_frequency = 1250000; //HVR-225x(saa7164), HVR-12xx(cx23885)
540 * if_frequency = 6600000; //HVR-9xx(cx231xx)
541 * if_frequency = 5500000; //HVR-19xx(pvrusb2)
543 dev_err(&client
->dev
, "si2157 does not currently support FM radio\n");
547 tmp_lval
= params
->frequency
* 625LL;
548 do_div(tmp_lval
, 10); /* convert to HZ */
549 freq
= (u32
)tmp_lval
;
551 if (freq
< 1000000) /* is freq in KHz */
553 dev
->frequency
= freq
;
555 /* if_frequency values based on tda187271C2 */
556 if (params
->std
& (V4L2_STD_B
| V4L2_STD_GH
)) {
557 if (freq
>= 470000000) {
560 if_frequency
= 6000000;
563 (V4L2_STD_SECAM_G
| V4L2_STD_SECAM_H
)) {
570 if_frequency
= 6000000;
572 if (params
->std
& V4L2_STD_SECAM_B
) {
577 } else if (params
->std
& V4L2_STD_MN
) {
580 if_frequency
= 5400000;
582 } else if (params
->std
& V4L2_STD_PAL_I
) {
585 if_frequency
= 7250000; /* TODO: does not work yet */
587 } else if (params
->std
& V4L2_STD_DK
) {
590 if_frequency
= 6900000; /* TODO: does not work yet */
592 if (params
->std
& V4L2_STD_SECAM_DK
) {
596 } else if (params
->std
& V4L2_STD_SECAM_L
) {
599 if_frequency
= 6750000; /* TODO: untested */
602 } else if (params
->std
& V4L2_STD_SECAM_LC
) {
605 if_frequency
= 1250000; /* TODO: untested */
611 /* calc channel center freq */
612 freq
= freq
- 1250000 + (bandwidth
/ 2);
614 dev_dbg(&client
->dev
,
615 "mode=%d system=%u std='%s' params->frequency=%u center freq=%u if=%u bandwidth=%u\n",
616 params
->mode
, system
, std
, params
->frequency
,
617 freq
, if_frequency
, bandwidth
);
619 /* set analog IF port */
620 memcpy(cmd
.args
, "\x14\x00\x03\x06\x08\x02", 6);
621 /* in using dev->if_port, we assume analog and digital IF's */
622 /* are always on different ports */
623 /* assumes if_port definition is 0 or 1 for digital out */
624 cmd
.args
[4] = (dev
->if_port
== 1) ? 8 : 10;
625 /* Analog AGC assumed external */
626 cmd
.args
[5] = (dev
->if_port
== 1) ? 2 : 1;
629 ret
= si2157_cmd_execute(client
, &cmd
);
633 /* set analog IF output config */
634 memcpy(cmd
.args
, "\x14\x00\x0d\x06\x94\x64", 6);
637 ret
= si2157_cmd_execute(client
, &cmd
);
641 /* make this distinct from a digital IF */
642 dev
->if_frequency
= if_frequency
| 1;
644 /* calc and set tuner analog if center frequency */
645 if_frequency
= if_frequency
+ 1250000 - (bandwidth
/ 2);
646 dev_dbg(&client
->dev
, "IF Ctr freq=%d\n", if_frequency
);
648 memcpy(cmd
.args
, "\x14\x00\x0C\x06", 4);
649 cmd
.args
[4] = (if_frequency
/ 1000) & 0xff;
650 cmd
.args
[5] = ((if_frequency
/ 1000) >> 8) & 0xff;
653 ret
= si2157_cmd_execute(client
, &cmd
);
657 /* set analog AGC config */
658 memcpy(cmd
.args
, "\x14\x00\x07\x06\x32\xc8", 6);
661 ret
= si2157_cmd_execute(client
, &cmd
);
665 /* set analog video mode */
666 memcpy(cmd
.args
, "\x14\x00\x04\x06\x00\x00", 6);
667 cmd
.args
[4] = system
| color
;
668 /* can use dev->inversion if assumed applies to both digital/analog */
673 ret
= si2157_cmd_execute(client
, &cmd
);
677 /* set analog frequency */
678 memcpy(cmd
.args
, "\x41\x01\x00\x00\x00\x00\x00\x00", 8);
679 cmd
.args
[4] = (freq
>> 0) & 0xff;
680 cmd
.args
[5] = (freq
>> 8) & 0xff;
681 cmd
.args
[6] = (freq
>> 16) & 0xff;
682 cmd
.args
[7] = (freq
>> 24) & 0xff;
685 ret
= si2157_cmd_execute(client
, &cmd
);
689 dev
->bandwidth
= bandwidth
;
691 si2157_tune_wait(client
, 0); /* wait to complete, ignore any errors */
697 dev
->if_frequency
= 0;
698 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
702 static int si2157_get_frequency(struct dvb_frontend
*fe
, u32
*frequency
)
704 struct i2c_client
*client
= fe
->tuner_priv
;
705 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
707 *frequency
= dev
->frequency
;
708 dev_dbg(&client
->dev
, "freq=%u\n", dev
->frequency
);
712 static int si2157_get_bandwidth(struct dvb_frontend
*fe
, u32
*bandwidth
)
714 struct i2c_client
*client
= fe
->tuner_priv
;
715 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
717 *bandwidth
= dev
->bandwidth
;
718 dev_dbg(&client
->dev
, "bandwidth=%u\n", dev
->bandwidth
);
722 static int si2157_get_if_frequency(struct dvb_frontend
*fe
, u32
*frequency
)
724 struct i2c_client
*client
= fe
->tuner_priv
;
725 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
727 *frequency
= dev
->if_frequency
& ~1; /* strip analog IF indicator bit */
728 dev_dbg(&client
->dev
, "if_frequency=%u\n", *frequency
);
732 static int si2157_get_rf_strength(struct dvb_frontend
*fe
, u16
*rssi
)
734 struct i2c_client
*client
= fe
->tuner_priv
;
735 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
736 struct si2157_cmd cmd
;
740 dev_dbg(&client
->dev
, "\n");
742 memcpy(cmd
.args
, "\x42\x00", 2);
745 ret
= si2157_cmd_execute(client
, &cmd
);
749 c
->strength
.stat
[0].scale
= FE_SCALE_DECIBEL
;
750 c
->strength
.stat
[0].svalue
= (s8
)cmd
.args
[3] * 1000;
752 /* normalize values based on Silicon Labs reference
753 * add 100, then anything > 80 is 100% signal
755 strength
= (s8
)cmd
.args
[3] + 100;
756 strength
= clamp_val(strength
, 0, 80);
757 *rssi
= (u16
)(strength
* 0xffff / 80);
759 dev_dbg(&client
->dev
, "strength=%d rssi=%u\n",
760 (s8
)cmd
.args
[3], *rssi
);
764 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
768 static const struct dvb_tuner_ops si2157_ops
= {
770 .name
= "Silicon Labs Si2141/Si2146/2147/2148/2157/2158",
771 .frequency_min_hz
= 42 * MHz
,
772 .frequency_max_hz
= 870 * MHz
,
776 .sleep
= si2157_sleep
,
777 .set_params
= si2157_set_params
,
778 .set_analog_params
= si2157_set_analog_params
,
779 .get_frequency
= si2157_get_frequency
,
780 .get_bandwidth
= si2157_get_bandwidth
,
781 .get_if_frequency
= si2157_get_if_frequency
,
783 .get_rf_strength
= si2157_get_rf_strength
,
786 static void si2157_stat_work(struct work_struct
*work
)
788 struct si2157_dev
*dev
= container_of(work
, struct si2157_dev
, stat_work
.work
);
789 struct dvb_frontend
*fe
= dev
->fe
;
790 struct i2c_client
*client
= fe
->tuner_priv
;
791 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
792 struct si2157_cmd cmd
;
795 dev_dbg(&client
->dev
, "\n");
797 memcpy(cmd
.args
, "\x42\x00", 2);
800 ret
= si2157_cmd_execute(client
, &cmd
);
804 c
->strength
.stat
[0].scale
= FE_SCALE_DECIBEL
;
805 c
->strength
.stat
[0].svalue
= (s8
) cmd
.args
[3] * 1000;
807 schedule_delayed_work(&dev
->stat_work
, msecs_to_jiffies(2000));
810 c
->strength
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
811 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
814 static int si2157_probe(struct i2c_client
*client
,
815 const struct i2c_device_id
*id
)
817 struct si2157_config
*cfg
= client
->dev
.platform_data
;
818 struct dvb_frontend
*fe
= cfg
->fe
;
819 struct si2157_dev
*dev
;
820 struct si2157_cmd cmd
;
823 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
826 dev_err(&client
->dev
, "kzalloc() failed\n");
830 i2c_set_clientdata(client
, dev
);
832 dev
->inversion
= cfg
->inversion
;
833 dev
->dont_load_firmware
= cfg
->dont_load_firmware
;
834 dev
->if_port
= cfg
->if_port
;
835 dev
->chiptype
= (u8
)id
->driver_data
;
836 dev
->if_frequency
= 5000000; /* default value of property 0x0706 */
837 mutex_init(&dev
->i2c_mutex
);
838 INIT_DELAYED_WORK(&dev
->stat_work
, si2157_stat_work
);
840 /* check if the tuner is there */
843 ret
= si2157_cmd_execute(client
, &cmd
);
844 if (ret
&& ret
!= -EAGAIN
)
847 memcpy(&fe
->ops
.tuner_ops
, &si2157_ops
, sizeof(struct dvb_tuner_ops
));
848 fe
->tuner_priv
= client
;
850 #ifdef CONFIG_MEDIA_CONTROLLER
852 dev
->mdev
= cfg
->mdev
;
854 dev
->ent
.name
= KBUILD_MODNAME
;
855 dev
->ent
.function
= MEDIA_ENT_F_TUNER
;
857 dev
->pad
[SI2157_PAD_RF_INPUT
].flags
= MEDIA_PAD_FL_SINK
;
858 dev
->pad
[SI2157_PAD_RF_INPUT
].sig_type
= PAD_SIGNAL_ANALOG
;
859 dev
->pad
[SI2157_PAD_VID_OUT
].flags
= MEDIA_PAD_FL_SOURCE
;
860 dev
->pad
[SI2157_PAD_VID_OUT
].sig_type
= PAD_SIGNAL_ANALOG
;
861 dev
->pad
[SI2157_PAD_AUD_OUT
].flags
= MEDIA_PAD_FL_SOURCE
;
862 dev
->pad
[SI2157_PAD_AUD_OUT
].sig_type
= PAD_SIGNAL_AUDIO
;
864 ret
= media_entity_pads_init(&dev
->ent
, SI2157_NUM_PADS
,
870 ret
= media_device_register_entity(cfg
->mdev
, &dev
->ent
);
872 media_entity_cleanup(&dev
->ent
);
878 dev_info(&client
->dev
, "Silicon Labs %s successfully attached\n",
879 dev
->chiptype
== SI2157_CHIPTYPE_SI2141
? "Si2141" :
880 dev
->chiptype
== SI2157_CHIPTYPE_SI2146
?
881 "Si2146" : "Si2147/2148/2157/2158");
888 dev_dbg(&client
->dev
, "failed=%d\n", ret
);
892 static int si2157_remove(struct i2c_client
*client
)
894 struct si2157_dev
*dev
= i2c_get_clientdata(client
);
895 struct dvb_frontend
*fe
= dev
->fe
;
897 dev_dbg(&client
->dev
, "\n");
899 /* stop statistics polling */
900 cancel_delayed_work_sync(&dev
->stat_work
);
902 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
904 media_device_unregister_entity(&dev
->ent
);
907 memset(&fe
->ops
.tuner_ops
, 0, sizeof(struct dvb_tuner_ops
));
908 fe
->tuner_priv
= NULL
;
914 static const struct i2c_device_id si2157_id_table
[] = {
915 {"si2157", SI2157_CHIPTYPE_SI2157
},
916 {"si2146", SI2157_CHIPTYPE_SI2146
},
917 {"si2141", SI2157_CHIPTYPE_SI2141
},
918 {"si2177", SI2157_CHIPTYPE_SI2177
},
921 MODULE_DEVICE_TABLE(i2c
, si2157_id_table
);
923 static struct i2c_driver si2157_driver
= {
926 .suppress_bind_attrs
= true,
928 .probe
= si2157_probe
,
929 .remove
= si2157_remove
,
930 .id_table
= si2157_id_table
,
933 module_i2c_driver(si2157_driver
);
935 MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon tuner driver");
936 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
937 MODULE_LICENSE("GPL");
938 MODULE_FIRMWARE(SI2158_A20_FIRMWARE
);
939 MODULE_FIRMWARE(SI2141_A10_FIRMWARE
);
940 MODULE_FIRMWARE(SI2157_A30_FIRMWARE
);