Lines Matching +full:sense +full:- +full:freq
1 // SPDX-License-Identifier: GPL-2.0
2 // tuner-xc2028
4 // Copyright (c) 2007-2008 Mauro Carvalho Chehab <mchehab@kernel.org>
7 // - frontend interface
18 #include "tuner-i2c.h"
19 #include "tuner-xc2028.h"
20 #include "tuner-xc2028-types.h"
28 /* Registers (Write-only) */
33 /* Registers (Read-only) */
125 _rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size); \
129 if (priv->ctrl.msleep) \
130 msleep(priv->ctrl.msleep); \
136 _rc = tuner_i2c_xfer_send_recv(&priv->i2c_props, obuf, osize, \
141 if (priv->ctrl.msleep) \
142 msleep(priv->ctrl.msleep); \
150 (_rc = tuner_i2c_xfer_send(&priv->i2c_props, \
153 } else if (priv->ctrl.msleep) \
154 msleep(priv->ctrl.msleep); \
169 return -EIO; in xc2028_get_reg()
262 switch (priv->state) { in check_device_status()
265 return -EAGAIN; in check_device_status()
271 return -ENODEV; in check_device_status()
282 if (priv->fname != firmware_name) in free_firmware()
283 kfree(priv->fname); in free_firmware()
284 priv->fname = NULL; in free_firmware()
286 priv->state = XC2028_NO_FIRMWARE; in free_firmware()
287 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); in free_firmware()
289 if (!priv->firm) in free_firmware()
292 for (i = 0; i < priv->firm_size; i++) in free_firmware()
293 kfree(priv->firm[i].ptr); in free_firmware()
295 kfree(priv->firm); in free_firmware()
297 priv->firm = NULL; in free_firmware()
298 priv->firm_size = 0; in free_firmware()
304 struct xc2028_data *priv = fe->tuner_priv; in load_all_firmwares()
312 p = fw->data; in load_all_firmwares()
313 endp = p + fw->size; in load_all_firmwares()
315 if (fw->size < sizeof(name) - 1 + 2 + 2) { in load_all_firmwares()
317 priv->fname); in load_all_firmwares()
321 memcpy(name, p, sizeof(name) - 1); in load_all_firmwares()
322 name[sizeof(name) - 1] = 0; in load_all_firmwares()
323 p += sizeof(name) - 1; in load_all_firmwares()
325 priv->firm_version = get_unaligned_le16(p); in load_all_firmwares()
332 n_array, priv->fname, name, in load_all_firmwares()
333 priv->firm_version >> 8, priv->firm_version & 0xff); in load_all_firmwares()
335 priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL); in load_all_firmwares()
336 if (priv->firm == NULL) { in load_all_firmwares()
338 rc = -ENOMEM; in load_all_firmwares()
341 priv->firm_size = n_array; in load_all_firmwares()
343 n = -1; in load_all_firmwares()
356 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size)) in load_all_firmwares()
368 if (endp - p < sizeof(size)) in load_all_firmwares()
375 if (!size || size > endp - p) { in load_all_firmwares()
380 type, (unsigned long long)id, (endp - p), size); in load_all_firmwares()
384 priv->firm[n].ptr = kmemdup(p, size, GFP_KERNEL); in load_all_firmwares()
385 if (priv->firm[n].ptr == NULL) { in load_all_firmwares()
387 rc = -ENOMEM; in load_all_firmwares()
397 priv->firm[n].type = type; in load_all_firmwares()
398 priv->firm[n].id = id; in load_all_firmwares()
399 priv->firm[n].size = size; in load_all_firmwares()
400 priv->firm[n].int_freq = int_freq; in load_all_firmwares()
405 if (n + 1 != priv->firm_size) { in load_all_firmwares()
415 rc = -EINVAL; in load_all_firmwares()
426 priv->state = XC2028_NODEV; in load_all_firmwares()
434 struct xc2028_data *priv = fe->tuner_priv; in seek_firmware()
435 int i, best_i = -1, best_nr_matches = 0; in seek_firmware()
445 if (!priv->firm) { in seek_firmware()
447 return -EINVAL; in seek_firmware()
469 for (i = 0; i < priv->firm_size; i++) { in seek_firmware()
470 if ((type == (priv->firm[i].type & type_mask)) && in seek_firmware()
471 (*id == priv->firm[i].id)) in seek_firmware()
476 for (i = 0; i < priv->firm_size; i++) { in seek_firmware()
480 if (type != (priv->firm[i].type & type_mask)) in seek_firmware()
483 match_mask = *id & priv->firm[i].id; in seek_firmware()
507 /*FIXME: Would make sense to seek for type "hint" match ? */ in seek_firmware()
509 i = -ENOENT; in seek_firmware()
513 *id = priv->firm[i].id; in seek_firmware()
527 struct xc2028_data *priv = fe->tuner_priv; in do_tuner_callback()
529 /* analog side (tuner-core) uses i2c_adap->algo_data. in do_tuner_callback()
532 * digital side will always have fe->dvb defined. in do_tuner_callback()
533 * analog side (tuner-core) doesn't (yet) define fe->dvb. in do_tuner_callback()
536 return (!fe->callback) ? -EINVAL : in do_tuner_callback()
537 fe->callback(((fe->dvb) && (fe->dvb->priv)) ? in do_tuner_callback()
538 fe->dvb->priv : priv->i2c_props.adap->algo_data, in do_tuner_callback()
545 struct xc2028_data *priv = fe->tuner_priv; in load_firmware()
549 if (priv->ctrl.max_len > sizeof(buf)) in load_firmware()
550 priv->ctrl.max_len = sizeof(buf); in load_firmware()
559 dump_firm_type(priv->firm[pos].type); in load_firmware()
561 priv->firm[pos].type, (unsigned long long)*id); in load_firmware()
563 p = priv->firm[pos].ptr; in load_firmware()
564 endp = p + priv->firm[pos].size; in load_firmware()
572 return -EINVAL; in load_firmware()
587 return -EINVAL; in load_firmware()
598 return -EINVAL; in load_firmware()
604 return -EINVAL; in load_firmware()
618 size, (endp - p)); in load_firmware()
619 return -EINVAL; in load_firmware()
624 size--; in load_firmware()
628 int len = (size < priv->ctrl.max_len - 1) ? in load_firmware()
629 size : priv->ctrl.max_len - 1; in load_firmware()
636 return -EINVAL; in load_firmware()
640 size -= len; in load_firmware()
645 if ((rc < 0) && (rc != -EINVAL)) { in load_firmware()
656 struct xc2028_data *priv = fe->tuner_priv; in load_scode()
667 for (pos = 0; pos < priv->firm_size; pos++) { in load_scode()
668 if ((priv->firm[pos].int_freq == int_freq) && in load_scode()
669 (priv->firm[pos].type & HAS_IF)) in load_scode()
672 if (pos == priv->firm_size) in load_scode()
673 return -ENOENT; in load_scode()
676 p = priv->firm[pos].ptr; in load_scode()
678 if (priv->firm[pos].type & HAS_IF) { in load_scode()
679 if (priv->firm[pos].size != 12 * 16 || scode >= 16) in load_scode()
680 return -EINVAL; in load_scode()
684 * has a 2-byte size header in the firmware format. */ in load_scode()
685 if (priv->firm[pos].size != 14 * 16 || scode >= 16 || in load_scode()
687 return -EINVAL; in load_scode()
692 dump_firm_type_and_int_freq(priv->firm[pos].type, in load_scode()
693 priv->firm[pos].int_freq); in load_scode()
694 printk(KERN_CONT "(%x), id %016llx.\n", priv->firm[pos].type, in load_scode()
697 if (priv->firm_version < 0x0202) in load_scode()
702 return -EIO; in load_scode()
706 return -EIO; in load_scode()
710 return -EIO; in load_scode()
720 struct xc2028_data *priv = fe->tuner_priv; in check_firmware()
732 if (priv->ctrl.mts && !(type & FM)) in check_firmware()
739 new_fw.scode_table = SCODE | priv->ctrl.scode_table; in check_firmware()
750 dump_firm_type(priv->ctrl.scode_table); in check_firmware()
751 printk(KERN_CONT "(%x), ", priv->ctrl.scode_table); in check_firmware()
761 if ((priv->state == XC2028_ACTIVE) && in check_firmware()
763 (priv->cur_fw.type & BASE_TYPES))) { in check_firmware()
768 /* Updating BASE - forget about all currently loaded firmware */ in check_firmware()
769 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); in check_firmware()
789 if (rc == -ENOENT) in check_firmware()
792 if (rc < 0 && rc != -ENOENT) { in check_firmware()
803 if (priv->cur_fw.type == (BASE | new_fw.type) && in check_firmware()
804 priv->cur_fw.std_req == std) { in check_firmware()
805 tuner_dbg("Std-specific firmware already loaded.\n"); in check_firmware()
809 /* Reloading std-specific firmware forces a SCODE update */ in check_firmware()
810 priv->cur_fw.scode_table = 0; in check_firmware()
813 if (rc == -ENOENT) in check_firmware()
820 if (priv->cur_fw.scode_table == new_fw.scode_table && in check_firmware()
821 priv->cur_fw.scode_nr == new_fw.scode_nr) { in check_firmware()
847 if (priv->ctrl.read_not_reliable) in check_firmware()
851 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) { in check_firmware()
852 if (!priv->ctrl.read_not_reliable) { in check_firmware()
862 if (priv->hwmodel == 0 && (hwmodel == 2028 || hwmodel == 3028)) { in check_firmware()
863 priv->hwmodel = hwmodel; in check_firmware()
864 priv->hwvers = version & 0xff00; in check_firmware()
865 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel || in check_firmware()
866 priv->hwvers != (version & 0xff00)) { in check_firmware()
867 tuner_err("Read invalid device hardware information - tuner hung?\n"); in check_firmware()
872 priv->cur_fw = new_fw; in check_firmware()
880 priv->cur_fw.type |= BASE; in check_firmware()
881 priv->state = XC2028_ACTIVE; in check_firmware()
898 if (rc == -ENOENT) in check_firmware()
899 rc = -EINVAL; in check_firmware()
905 struct xc2028_data *priv = fe->tuner_priv; in xc2028_signal()
921 mutex_lock(&priv->lock); in xc2028_signal()
945 signal = ((1 << 12) - 1) | ((signal & 0x07) << 12); in xc2028_signal()
948 mutex_unlock(&priv->lock); in xc2028_signal()
959 struct xc2028_data *priv = fe->tuner_priv; in xc2028_get_afc()
974 mutex_lock(&priv->lock); in xc2028_get_afc()
1001 mutex_unlock(&priv->lock); in xc2028_get_afc()
1008 static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, in generic_set_freq() argument
1014 struct xc2028_data *priv = fe->tuner_priv; in generic_set_freq()
1015 int rc = -EINVAL; in generic_set_freq()
1021 mutex_lock(&priv->lock); in generic_set_freq()
1023 tuner_dbg("should set frequency %d kHz\n", freq / 1000); in generic_set_freq()
1030 * reset, this is re-enabled. So, it is better to always in generic_set_freq()
1053 * formula: offset = 1.25MHz - BW/2 in generic_set_freq()
1071 if (priv->cur_fw.type & DTV6) in generic_set_freq()
1085 * The proper adjustment would be to do it at s-code table. in generic_set_freq()
1093 * So, for now, let's just comment the per-firmware in generic_set_freq()
1098 if (priv->firm_version < 0x0302) { in generic_set_freq()
1099 if (priv->cur_fw.type & DTV7) in generic_set_freq()
1102 if (priv->cur_fw.type & DTV7) in generic_set_freq()
1103 offset -= 300000; in generic_set_freq()
1114 div = (freq - offset + DIV / 2) / DIV; in generic_set_freq()
1117 if (priv->firm_version < 0x0202) in generic_set_freq()
1128 if (priv->ctrl.msleep) in generic_set_freq()
1129 msleep(priv->ctrl.msleep); in generic_set_freq()
1144 priv->frequency = freq; in generic_set_freq()
1146 tuner_dbg("divisor= %*ph (freq=%d.%03d)\n", 4, buf, in generic_set_freq()
1147 freq / 1000000, (freq % 1000000) / 1000); in generic_set_freq()
1152 mutex_unlock(&priv->lock); in generic_set_freq()
1160 struct xc2028_data *priv = fe->tuner_priv; in xc2028_set_analog_freq()
1165 if (p->mode == V4L2_TUNER_RADIO) { in xc2028_set_analog_freq()
1167 if (priv->ctrl.input1) in xc2028_set_analog_freq()
1169 return generic_set_freq(fe, (625l * p->frequency) / 10, in xc2028_set_analog_freq()
1174 if (!p->std) in xc2028_set_analog_freq()
1175 p->std = V4L2_STD_MN; in xc2028_set_analog_freq()
1178 if (!(p->std & V4L2_STD_MN)) in xc2028_set_analog_freq()
1182 p->std |= parse_audio_std_option(); in xc2028_set_analog_freq()
1184 return generic_set_freq(fe, 62500l * p->frequency, in xc2028_set_analog_freq()
1185 V4L2_TUNER_ANALOG_TV, type, p->std, 0); in xc2028_set_analog_freq()
1190 struct dtv_frontend_properties *c = &fe->dtv_property_cache; in xc2028_set_params()
1191 u32 delsys = c->delivery_system; in xc2028_set_params()
1192 u32 bw = c->bandwidth_hz; in xc2028_set_params()
1193 struct xc2028_data *priv = fe->tuner_priv; in xc2028_set_params()
1215 switch (priv->ctrl.type) { in xc2028_set_params()
1225 if (priv->ctrl.demod == XC3028_FE_ZARLINK456) in xc2028_set_params()
1235 /* DVB-S and pure QAM (FE_QAM) are not supported */ in xc2028_set_params()
1237 return -EINVAL; in xc2028_set_params()
1242 priv->ctrl.vhfbw7 = 0; in xc2028_set_params()
1243 priv->ctrl.uhfbw8 = 0; in xc2028_set_params()
1245 if (c->frequency < 470000000) in xc2028_set_params()
1246 priv->ctrl.vhfbw7 = 1; in xc2028_set_params()
1248 priv->ctrl.uhfbw8 = 0; in xc2028_set_params()
1249 type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV7; in xc2028_set_params()
1252 if (c->frequency < 470000000) in xc2028_set_params()
1253 priv->ctrl.vhfbw7 = 0; in xc2028_set_params()
1255 priv->ctrl.uhfbw8 = 1; in xc2028_set_params()
1256 type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV8; in xc2028_set_params()
1260 /* All S-code tables need a 200kHz shift */ in xc2028_set_params()
1261 if (priv->ctrl.demod) { in xc2028_set_params()
1262 demod = priv->ctrl.demod; in xc2028_set_params()
1267 if (type == ATSC || priv->firm_version < 0x0302) in xc2028_set_params()
1270 * The DTV7 S-code table needs a 700 kHz shift. in xc2028_set_params()
1276 * Unfortunately, on real-field tests, the s-code offset in xc2028_set_params()
1282 return generic_set_freq(fe, c->frequency, in xc2028_set_params()
1288 struct xc2028_data *priv = fe->tuner_priv; in xc2028_sleep()
1300 if (no_poweroff || priv->ctrl.disable_power_mgmt) in xc2028_sleep()
1309 mutex_lock(&priv->lock); in xc2028_sleep()
1311 if (priv->firm_version < 0x0202) in xc2028_sleep()
1317 priv->state = XC2028_SLEEP; in xc2028_sleep()
1319 mutex_unlock(&priv->lock); in xc2028_sleep()
1326 struct xc2028_data *priv = fe->tuner_priv; in xc2028_dvb_release()
1341 fe->tuner_priv = NULL; in xc2028_dvb_release()
1346 struct xc2028_data *priv = fe->tuner_priv; in xc2028_get_frequency()
1355 *frequency = priv->frequency; in xc2028_get_frequency()
1364 struct xc2028_data *priv = fe->tuner_priv; in load_firmware_cb()
1369 tuner_err("Could not load firmware %s.\n", priv->fname); in load_firmware_cb()
1370 priv->state = XC2028_NODEV; in load_firmware_cb()
1380 priv->state = XC2028_ACTIVE; in load_firmware_cb()
1385 struct xc2028_data *priv = fe->tuner_priv; in xc2028_set_config()
1391 mutex_lock(&priv->lock); in xc2028_set_config()
1396 memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); in xc2028_set_config()
1402 if (!firmware_name[0] && p->fname && in xc2028_set_config()
1403 priv->fname && strcmp(p->fname, priv->fname)) in xc2028_set_config()
1406 if (priv->ctrl.max_len < 9) in xc2028_set_config()
1407 priv->ctrl.max_len = 13; in xc2028_set_config()
1409 if (priv->state == XC2028_NO_FIRMWARE) { in xc2028_set_config()
1411 priv->fname = kstrdup(p->fname, GFP_KERNEL); in xc2028_set_config()
1413 priv->fname = firmware_name; in xc2028_set_config()
1415 if (!priv->fname) { in xc2028_set_config()
1416 rc = -ENOMEM; in xc2028_set_config()
1421 priv->fname, in xc2028_set_config()
1422 priv->i2c_props.adap->dev.parent, in xc2028_set_config()
1427 priv->fname); in xc2028_set_config()
1428 priv->state = XC2028_NODEV; in xc2028_set_config()
1430 priv->state = XC2028_WAITING_FIRMWARE; in xc2028_set_config()
1433 mutex_unlock(&priv->lock); in xc2028_set_config()
1477 cfg->i2c_adap, cfg->i2c_addr, in xc2028_attach()
1485 priv->ctrl.max_len = 13; in xc2028_attach()
1487 mutex_init(&priv->lock); in xc2028_attach()
1489 fe->tuner_priv = priv; in xc2028_attach()
1493 fe->tuner_priv = priv; in xc2028_attach()
1497 memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops, in xc2028_attach()
1502 if (cfg->ctrl) in xc2028_attach()
1503 xc2028_set_config(fe, cfg->ctrl); in xc2028_attach()