Lines Matching +full:silicon +full:- +full:id

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver
23 mutex_lock(&dev->i2c_mutex); in si2157_cmd_execute()
25 if (cmd->wlen) { in si2157_cmd_execute()
27 ret = i2c_master_send(client, cmd->args, cmd->wlen); in si2157_cmd_execute()
30 } else if (ret != cmd->wlen) { in si2157_cmd_execute()
31 ret = -EREMOTEIO; in si2157_cmd_execute()
36 if (cmd->rlen) { in si2157_cmd_execute()
41 ret = i2c_master_recv(client, cmd->args, cmd->rlen); in si2157_cmd_execute()
44 } else if (ret != cmd->rlen) { in si2157_cmd_execute()
45 ret = -EREMOTEIO; in si2157_cmd_execute()
50 if ((cmd->args[0] >> 7) & 0x01) in si2157_cmd_execute()
54 dev_dbg(&client->dev, "cmd execution took %d ms, status=%x\n", in si2157_cmd_execute()
55 jiffies_to_msecs(jiffies) - in si2157_cmd_execute()
56 (jiffies_to_msecs(timeout) - TIMEOUT), in si2157_cmd_execute()
57 cmd->args[0]); in si2157_cmd_execute()
59 if (!((cmd->args[0] >> 7) & 0x01)) { in si2157_cmd_execute()
60 ret = -ETIMEDOUT; in si2157_cmd_execute()
64 if (cmd->args[0] & 0x40) { in si2157_cmd_execute()
65 ret = -EAGAIN; in si2157_cmd_execute()
70 mutex_unlock(&dev->i2c_mutex); in si2157_cmd_execute()
74 mutex_unlock(&dev->i2c_mutex); in si2157_cmd_execute()
75 dev_dbg(&client->dev, "failed=%d\n", ret); in si2157_cmd_execute()
95 struct i2c_client *client = fe->tuner_priv; in si2157_load_firmware()
101 ret = firmware_request_nowarn(&fw, fw_name, &client->dev); in si2157_load_firmware()
106 if (fw->size % 17 != 0) { in si2157_load_firmware()
107 dev_err(&client->dev, "firmware file '%s' is invalid\n", in si2157_load_firmware()
109 ret = -EINVAL; in si2157_load_firmware()
113 dev_info(&client->dev, "downloading firmware from file '%s'\n", in si2157_load_firmware()
116 for (remaining = fw->size; remaining > 0; remaining -= 17) { in si2157_load_firmware()
117 len = fw->data[fw->size - remaining]; in si2157_load_firmware()
119 dev_err(&client->dev, "Bad firmware length\n"); in si2157_load_firmware()
120 ret = -EINVAL; in si2157_load_firmware()
123 memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len); in si2157_load_firmware()
128 dev_err(&client->dev, "firmware download failed %d\n", in si2157_load_firmware()
142 struct i2c_client *client = fe->tuner_priv; in si2157_find_and_load_firmware()
151 if (dev->dont_load_firmware) { in si2157_find_and_load_firmware()
152 dev_info(&client->dev, in si2157_find_and_load_firmware()
174 /* Both part and rom ID match */ in si2157_find_and_load_firmware()
182 dev_err(&client->dev, in si2157_find_and_load_firmware()
183 "unknown chip version Si21%d-%c%c%c ROM 0x%02x\n", in si2157_find_and_load_firmware()
185 return -EINVAL; in si2157_find_and_load_firmware()
188 /* Update the part id based on device's report */ in si2157_find_and_load_firmware()
189 dev->part_id = part_id; in si2157_find_and_load_firmware()
191 dev_info(&client->dev, in si2157_find_and_load_firmware()
192 "found a 'Silicon Labs Si21%d-%c%c%c ROM 0x%02x'\n", in si2157_find_and_load_firmware()
198 ret = -ENOENT; in si2157_find_and_load_firmware()
201 if (ret == -ENOENT && fw_alt_name) in si2157_find_and_load_firmware()
204 if (ret == -ENOENT) { in si2157_find_and_load_firmware()
206 dev_info(&client->dev, "Using ROM firmware.\n"); in si2157_find_and_load_firmware()
209 dev_err(&client->dev, "Can't continue without a firmware.\n"); in si2157_find_and_load_firmware()
211 dev_err(&client->dev, "error %d when loading firmware\n", ret); in si2157_find_and_load_firmware()
218 struct dtv_frontend_properties *c = &fe->dtv_property_cache; in si2157_init()
219 struct i2c_client *client = fe->tuner_priv; in si2157_init()
225 dev_dbg(&client->dev, "\n"); in si2157_init()
238 dev->if_frequency = 0; /* we no longer know current tuner state */ in si2157_init()
241 if (dev->part_id == SI2146) { in si2157_init()
245 } else if (dev->part_id == SI2141) { in si2157_init()
255 if (ret && (dev->part_id != SI2141 || ret != -EAGAIN)) in si2157_init()
259 if (dev->part_id == SI2141) { in si2157_init()
288 dev_info(&client->dev, "firmware version: %c.%c.%d\n", in si2157_init()
314 c->strength.len = 1; in si2157_init()
315 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in si2157_init()
317 schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(1000)); in si2157_init()
319 dev->active = true; in si2157_init()
323 dev_dbg(&client->dev, "failed=%d\n", ret); in si2157_init()
329 struct i2c_client *client = fe->tuner_priv; in si2157_sleep()
334 dev_dbg(&client->dev, "\n"); in si2157_sleep()
336 dev->active = false; in si2157_sleep()
339 cancel_delayed_work_sync(&dev->stat_work); in si2157_sleep()
351 dev_dbg(&client->dev, "failed=%d\n", ret); in si2157_sleep()
372 mutex_lock(&dev->i2c_mutex); in si2157_tune_wait()
383 ret = -EREMOTEIO; in si2157_tune_wait()
396 dev_dbg(&client->dev, "tuning took %d ms, status=0x%x\n", in si2157_tune_wait()
397 jiffies_to_msecs(jiffies) - jiffies_to_msecs(start_time), in si2157_tune_wait()
413 ret = -EREMOTEIO; in si2157_tune_wait()
423 dev_dbg(&client->dev, "tuning+lock took %d ms, status=0x%x\n", in si2157_tune_wait()
424 jiffies_to_msecs(jiffies) - jiffies_to_msecs(start_time), in si2157_tune_wait()
429 ret = -ETIMEDOUT; in si2157_tune_wait()
433 mutex_unlock(&dev->i2c_mutex); in si2157_tune_wait()
437 mutex_unlock(&dev->i2c_mutex); in si2157_tune_wait()
438 dev_err(&client->dev, "failed=%d\n", ret); in si2157_tune_wait()
444 struct i2c_client *client = fe->tuner_priv; in si2157_set_params()
446 struct dtv_frontend_properties *c = &fe->dtv_property_cache; in si2157_set_params()
453 dev_dbg(&client->dev, in si2157_set_params()
455 c->delivery_system, c->frequency, c->bandwidth_hz); in si2157_set_params()
457 if (!dev->active) { in si2157_set_params()
458 ret = -EAGAIN; in si2157_set_params()
462 if (SUPPORTS_1700KHz(dev) && c->bandwidth_hz <= 1700000) { in si2157_set_params()
465 } else if (c->bandwidth_hz <= 6000000) { in si2157_set_params()
468 } else if (SUPPORTS_1700KHz(dev) && c->bandwidth_hz <= 6100000) { in si2157_set_params()
471 } else if (c->bandwidth_hz <= 7000000) { in si2157_set_params()
479 switch (c->delivery_system) { in si2157_set_params()
489 case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */ in si2157_set_params()
503 ret = -EINVAL; in si2157_set_params()
509 if (dev->inversion) in si2157_set_params()
518 if (dev->part_id == SI2146) in si2157_set_params()
522 cmd.args[4] = dev->if_port; in si2157_set_params()
530 if (if_frequency != dev->if_frequency) { in si2157_set_params()
540 dev->if_frequency = if_frequency; in si2157_set_params()
545 cmd.args[4] = (c->frequency >> 0) & 0xff; in si2157_set_params()
546 cmd.args[5] = (c->frequency >> 8) & 0xff; in si2157_set_params()
547 cmd.args[6] = (c->frequency >> 16) & 0xff; in si2157_set_params()
548 cmd.args[7] = (c->frequency >> 24) & 0xff; in si2157_set_params()
555 dev->bandwidth = bandwidth; in si2157_set_params()
556 dev->frequency = c->frequency; in si2157_set_params()
562 dev->bandwidth = 0; in si2157_set_params()
563 dev->frequency = 0; in si2157_set_params()
564 dev->if_frequency = 0; in si2157_set_params()
565 dev_dbg(&client->dev, "failed=%d\n", ret); in si2157_set_params()
572 struct i2c_client *client = fe->tuner_priv; in si2157_set_analog_params()
586 dev_info(&client->dev, "Analog tuning not supported yet for Si21%d\n", in si2157_set_analog_params()
587 dev->part_id); in si2157_set_analog_params()
588 ret = -EINVAL; in si2157_set_analog_params()
592 if (!dev->active) in si2157_set_analog_params()
595 if (!dev->active) { in si2157_set_analog_params()
596 ret = -EAGAIN; in si2157_set_analog_params()
599 if (params->mode == V4L2_TUNER_RADIO) { in si2157_set_analog_params()
603 * if_frequency = 1250000; //HVR-225x(saa7164), HVR-12xx(cx23885) in si2157_set_analog_params()
604 * if_frequency = 6600000; //HVR-9xx(cx231xx) in si2157_set_analog_params()
605 * if_frequency = 5500000; //HVR-19xx(pvrusb2) in si2157_set_analog_params()
607 dev_err(&client->dev, "si2157 does not currently support FM radio\n"); in si2157_set_analog_params()
608 ret = -EINVAL; in si2157_set_analog_params()
611 tmp_lval = params->frequency * 625LL; in si2157_set_analog_params()
617 dev->frequency = freq; in si2157_set_analog_params()
620 if (params->std & (V4L2_STD_B | V4L2_STD_GH)) { in si2157_set_analog_params()
626 if (params->std & in si2157_set_analog_params()
636 if (params->std & V4L2_STD_SECAM_B) { in si2157_set_analog_params()
641 } else if (params->std & V4L2_STD_MN) { in si2157_set_analog_params()
646 } else if (params->std & V4L2_STD_PAL_I) { in si2157_set_analog_params()
651 } else if (params->std & V4L2_STD_DK) { in si2157_set_analog_params()
656 if (params->std & V4L2_STD_SECAM_DK) { in si2157_set_analog_params()
660 } else if (params->std & V4L2_STD_SECAM_L) { in si2157_set_analog_params()
666 } else if (params->std & V4L2_STD_SECAM_LC) { in si2157_set_analog_params()
676 freq = freq - 1250000 + (bandwidth / 2); in si2157_set_analog_params()
678 dev_dbg(&client->dev, in si2157_set_analog_params()
679 "mode=%d system=%u std='%s' params->frequency=%u center freq=%u if=%u bandwidth=%u\n", in si2157_set_analog_params()
680 params->mode, system, std, params->frequency, in si2157_set_analog_params()
685 /* in using dev->if_port, we assume analog and digital IF's */ in si2157_set_analog_params()
688 cmd.args[4] = (dev->if_port == 1) ? 8 : 10; in si2157_set_analog_params()
690 cmd.args[5] = (dev->if_port == 1) ? 2 : 1; in si2157_set_analog_params()
706 dev->if_frequency = if_frequency | 1; in si2157_set_analog_params()
709 if_frequency = if_frequency + 1250000 - (bandwidth / 2); in si2157_set_analog_params()
710 dev_dbg(&client->dev, "IF Ctr freq=%d\n", if_frequency); in si2157_set_analog_params()
732 /* can use dev->inversion if assumed applies to both digital/analog */ in si2157_set_analog_params()
753 dev->bandwidth = bandwidth; in si2157_set_analog_params()
759 dev->bandwidth = 0; in si2157_set_analog_params()
760 dev->frequency = 0; in si2157_set_analog_params()
761 dev->if_frequency = 0; in si2157_set_analog_params()
762 dev_dbg(&client->dev, "failed=%d\n", ret); in si2157_set_analog_params()
768 struct i2c_client *client = fe->tuner_priv; in si2157_get_frequency()
771 *frequency = dev->frequency; in si2157_get_frequency()
772 dev_dbg(&client->dev, "freq=%u\n", dev->frequency); in si2157_get_frequency()
778 struct i2c_client *client = fe->tuner_priv; in si2157_get_bandwidth()
781 *bandwidth = dev->bandwidth; in si2157_get_bandwidth()
782 dev_dbg(&client->dev, "bandwidth=%u\n", dev->bandwidth); in si2157_get_bandwidth()
788 struct i2c_client *client = fe->tuner_priv; in si2157_get_if_frequency()
791 *frequency = dev->if_frequency & ~1; /* strip analog IF indicator bit */ in si2157_get_if_frequency()
792 dev_dbg(&client->dev, "if_frequency=%u\n", *frequency); in si2157_get_if_frequency()
798 struct i2c_client *client = fe->tuner_priv; in si2157_get_rf_strength()
799 struct dtv_frontend_properties *c = &fe->dtv_property_cache; in si2157_get_rf_strength()
804 dev_dbg(&client->dev, "\n"); in si2157_get_rf_strength()
813 c->strength.stat[0].scale = FE_SCALE_DECIBEL; in si2157_get_rf_strength()
814 c->strength.stat[0].svalue = (s8)cmd.args[3] * 1000; in si2157_get_rf_strength()
816 /* normalize values based on Silicon Labs reference in si2157_get_rf_strength()
823 dev_dbg(&client->dev, "strength=%d rssi=%u\n", in si2157_get_rf_strength()
828 dev_dbg(&client->dev, "failed=%d\n", ret); in si2157_get_rf_strength()
834 .name = "Silicon Labs Si2141/Si2146/2147/2148/2157/2158",
853 struct dvb_frontend *fe = dev->fe; in si2157_stat_work()
854 struct i2c_client *client = fe->tuner_priv; in si2157_stat_work()
855 struct dtv_frontend_properties *c = &fe->dtv_property_cache; in si2157_stat_work()
859 dev_dbg(&client->dev, "\n"); in si2157_stat_work()
868 c->strength.stat[0].scale = FE_SCALE_DECIBEL; in si2157_stat_work()
869 c->strength.stat[0].svalue = (s8) cmd.args[3] * 1000; in si2157_stat_work()
871 schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000)); in si2157_stat_work()
874 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; in si2157_stat_work()
875 dev_dbg(&client->dev, "failed=%d\n", ret); in si2157_stat_work()
880 const struct i2c_device_id *id = i2c_client_get_device_id(client); in si2157_probe() local
881 struct si2157_config *cfg = client->dev.platform_data; in si2157_probe()
882 struct dvb_frontend *fe = cfg->fe; in si2157_probe()
889 ret = -ENOMEM; in si2157_probe()
890 dev_err(&client->dev, "kzalloc() failed\n"); in si2157_probe()
895 dev->fe = cfg->fe; in si2157_probe()
896 dev->inversion = cfg->inversion; in si2157_probe()
897 dev->dont_load_firmware = cfg->dont_load_firmware; in si2157_probe()
898 dev->if_port = cfg->if_port; in si2157_probe()
899 dev->part_id = (u8)id->driver_data; in si2157_probe()
900 dev->if_frequency = 5000000; /* default value of property 0x0706 */ in si2157_probe()
901 mutex_init(&dev->i2c_mutex); in si2157_probe()
902 INIT_DELAYED_WORK(&dev->stat_work, si2157_stat_work); in si2157_probe()
908 if (ret && ret != -EAGAIN) in si2157_probe()
911 memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops)); in si2157_probe()
912 fe->tuner_priv = client; in si2157_probe()
915 if (cfg->mdev) { in si2157_probe()
916 dev->mdev = cfg->mdev; in si2157_probe()
918 dev->ent.name = KBUILD_MODNAME; in si2157_probe()
919 dev->ent.function = MEDIA_ENT_F_TUNER; in si2157_probe()
921 dev->pad[SI2157_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK; in si2157_probe()
922 dev->pad[SI2157_PAD_RF_INPUT].sig_type = PAD_SIGNAL_ANALOG; in si2157_probe()
923 dev->pad[SI2157_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE; in si2157_probe()
924 dev->pad[SI2157_PAD_VID_OUT].sig_type = PAD_SIGNAL_ANALOG; in si2157_probe()
925 dev->pad[SI2157_PAD_AUD_OUT].flags = MEDIA_PAD_FL_SOURCE; in si2157_probe()
926 dev->pad[SI2157_PAD_AUD_OUT].sig_type = PAD_SIGNAL_AUDIO; in si2157_probe()
928 ret = media_entity_pads_init(&dev->ent, SI2157_NUM_PADS, in si2157_probe()
929 &dev->pad[0]); in si2157_probe()
934 ret = media_device_register_entity(cfg->mdev, &dev->ent); in si2157_probe()
936 media_entity_cleanup(&dev->ent); in si2157_probe()
942 dev_info(&client->dev, "Silicon Labs Si21%d successfully attached\n", in si2157_probe()
943 dev->part_id); in si2157_probe()
950 dev_dbg(&client->dev, "failed=%d\n", ret); in si2157_probe()
957 struct dvb_frontend *fe = dev->fe; in si2157_remove()
959 dev_dbg(&client->dev, "\n"); in si2157_remove()
962 cancel_delayed_work_sync(&dev->stat_work); in si2157_remove()
965 if (dev->mdev) in si2157_remove()
966 media_device_unregister_entity(&dev->ent); in si2157_remove()
969 memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); in si2157_remove()
970 fe->tuner_priv = NULL; in si2157_remove()
976 * accept firmware uploads. Non-buggy devices should just use "si2157" for
977 * all SiLabs TER tuners, as the driver should auto-detect it.
1000 MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon tuner driver");