aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/tuners/tuner-xc2028.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/common/tuners/tuner-xc2028.c')
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c74
1 files changed, 45 insertions, 29 deletions
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index 4dd1d2421cc5..b65e6803e6c6 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -71,9 +71,6 @@ struct firmware_properties {
71struct xc2028_data { 71struct xc2028_data {
72 struct list_head hybrid_tuner_instance_list; 72 struct list_head hybrid_tuner_instance_list;
73 struct tuner_i2c_props i2c_props; 73 struct tuner_i2c_props i2c_props;
74 int (*tuner_callback) (void *dev,
75 int command, int arg);
76 void *video_dev;
77 __u32 frequency; 74 __u32 frequency;
78 75
79 struct firmware_description *firm; 76 struct firmware_description *firm;
@@ -492,6 +489,23 @@ ret:
492 return i; 489 return i;
493} 490}
494 491
492static inline int do_tuner_callback(struct dvb_frontend *fe, int cmd, int arg)
493{
494 struct xc2028_data *priv = fe->tuner_priv;
495
496 /* analog side (tuner-core) uses i2c_adap->algo_data.
497 * digital side is not guaranteed to have algo_data defined.
498 *
499 * digital side will always have fe->dvb defined.
500 * analog side (tuner-core) doesn't (yet) define fe->dvb.
501 */
502
503 return (!fe->callback) ? -EINVAL :
504 fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
505 fe->dvb->priv : priv->i2c_props.adap->algo_data,
506 DVB_FRONTEND_COMPONENT_TUNER, cmd, arg);
507}
508
495static int load_firmware(struct dvb_frontend *fe, unsigned int type, 509static int load_firmware(struct dvb_frontend *fe, unsigned int type,
496 v4l2_std_id *id) 510 v4l2_std_id *id)
497{ 511{
@@ -530,8 +544,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type,
530 544
531 if (!size) { 545 if (!size) {
532 /* Special callback command received */ 546 /* Special callback command received */
533 rc = priv->tuner_callback(priv->video_dev, 547 rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0);
534 XC2028_TUNER_RESET, 0);
535 if (rc < 0) { 548 if (rc < 0) {
536 tuner_err("Error at RESET code %d\n", 549 tuner_err("Error at RESET code %d\n",
537 (*p) & 0x7f); 550 (*p) & 0x7f);
@@ -542,8 +555,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type,
542 if (size >= 0xff00) { 555 if (size >= 0xff00) {
543 switch (size) { 556 switch (size) {
544 case 0xff00: 557 case 0xff00:
545 rc = priv->tuner_callback(priv->video_dev, 558 rc = do_tuner_callback(fe, XC2028_RESET_CLK, 0);
546 XC2028_RESET_CLK, 0);
547 if (rc < 0) { 559 if (rc < 0) {
548 tuner_err("Error at RESET code %d\n", 560 tuner_err("Error at RESET code %d\n",
549 (*p) & 0x7f); 561 (*p) & 0x7f);
@@ -715,8 +727,7 @@ retry:
715 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); 727 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
716 728
717 /* Reset is needed before loading firmware */ 729 /* Reset is needed before loading firmware */
718 rc = priv->tuner_callback(priv->video_dev, 730 rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0);
719 XC2028_TUNER_RESET, 0);
720 if (rc < 0) 731 if (rc < 0)
721 goto fail; 732 goto fail;
722 733
@@ -933,7 +944,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
933 The reset CLK is needed only with tm6000. 944 The reset CLK is needed only with tm6000.
934 Driver should work fine even if this fails. 945 Driver should work fine even if this fails.
935 */ 946 */
936 priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1); 947 do_tuner_callback(fe, XC2028_RESET_CLK, 1);
937 948
938 msleep(10); 949 msleep(10);
939 950
@@ -1002,11 +1013,6 @@ static int xc2028_set_params(struct dvb_frontend *fe,
1002 1013
1003 tuner_dbg("%s called\n", __func__); 1014 tuner_dbg("%s called\n", __func__);
1004 1015
1005 if (priv->ctrl.d2633)
1006 type |= D2633;
1007 else
1008 type |= D2620;
1009
1010 switch(fe->ops.info.type) { 1016 switch(fe->ops.info.type) {
1011 case FE_OFDM: 1017 case FE_OFDM:
1012 bw = p->u.ofdm.bandwidth; 1018 bw = p->u.ofdm.bandwidth;
@@ -1021,10 +1027,8 @@ static int xc2028_set_params(struct dvb_frontend *fe,
1021 break; 1027 break;
1022 case FE_ATSC: 1028 case FE_ATSC:
1023 bw = BANDWIDTH_6_MHZ; 1029 bw = BANDWIDTH_6_MHZ;
1024 /* The only ATSC firmware (at least on v2.7) is D2633, 1030 /* The only ATSC firmware (at least on v2.7) is D2633 */
1025 so overrides ctrl->d2633 */ 1031 type |= ATSC | D2633;
1026 type |= ATSC| D2633;
1027 type &= ~D2620;
1028 break; 1032 break;
1029 /* DVB-S is not supported */ 1033 /* DVB-S is not supported */
1030 default: 1034 default:
@@ -1057,6 +1061,28 @@ static int xc2028_set_params(struct dvb_frontend *fe,
1057 tuner_err("error: bandwidth not supported.\n"); 1061 tuner_err("error: bandwidth not supported.\n");
1058 }; 1062 };
1059 1063
1064 /*
1065 Selects between D2633 or D2620 firmware.
1066 It doesn't make sense for ATSC, since it should be D2633 on all cases
1067 */
1068 if (fe->ops.info.type != FE_ATSC) {
1069 switch (priv->ctrl.type) {
1070 case XC2028_D2633:
1071 type |= D2633;
1072 break;
1073 case XC2028_D2620:
1074 type |= D2620;
1075 break;
1076 case XC2028_AUTO:
1077 default:
1078 /* Zarlink seems to need D2633 */
1079 if (priv->ctrl.demod == XC3028_FE_ZARLINK456)
1080 type |= D2633;
1081 else
1082 type |= D2620;
1083 }
1084 }
1085
1060 /* All S-code tables need a 200kHz shift */ 1086 /* All S-code tables need a 200kHz shift */
1061 if (priv->ctrl.demod) 1087 if (priv->ctrl.demod)
1062 demod = priv->ctrl.demod + 200; 1088 demod = priv->ctrl.demod + 200;
@@ -1177,20 +1203,10 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
1177 break; 1203 break;
1178 case 1: 1204 case 1:
1179 /* new tuner instance */ 1205 /* new tuner instance */
1180 priv->tuner_callback = cfg->callback;
1181 priv->ctrl.max_len = 13; 1206 priv->ctrl.max_len = 13;
1182 1207
1183 mutex_init(&priv->lock); 1208 mutex_init(&priv->lock);
1184 1209
1185 /* analog side (tuner-core) uses i2c_adap->algo_data.
1186 * digital side is not guaranteed to have algo_data defined.
1187 *
1188 * digital side will always have fe->dvb defined.
1189 * analog side (tuner-core) doesn't (yet) define fe->dvb.
1190 */
1191 priv->video_dev = ((fe->dvb) && (fe->dvb->priv)) ?
1192 fe->dvb->priv : cfg->i2c_adap->algo_data;
1193
1194 fe->tuner_priv = priv; 1210 fe->tuner_priv = priv;
1195 break; 1211 break;
1196 case 2: 1212 case 2: