aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/frontends/cx24116.c89
1 files changed, 68 insertions, 21 deletions
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
index 02ed4ef79c67..808ef2995d80 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -84,7 +84,8 @@ static int debug = 0;
84#define CX24116_ROLLOFF_035 (0x02) 84#define CX24116_ROLLOFF_035 (0x02)
85 85
86/* pilot bit */ 86/* pilot bit */
87#define CX24116_PILOT (0x40) 87#define CX24116_PILOT_OFF (0x00)
88#define CX24116_PILOT_ON (0x40)
88 89
89/* signal status */ 90/* signal status */
90#define CX24116_HAS_SIGNAL (0x01) 91#define CX24116_HAS_SIGNAL (0x01)
@@ -148,6 +149,7 @@ struct cx24116_tuning
148 u8 fec_val; 149 u8 fec_val;
149 u8 fec_mask; 150 u8 fec_mask;
150 u8 inversion_val; 151 u8 inversion_val;
152 u8 pilot_val;
151 u8 rolloff_val; 153 u8 rolloff_val;
152}; 154};
153 155
@@ -1121,25 +1123,62 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
1121 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 1123 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1122 struct cx24116_cmd cmd; 1124 struct cx24116_cmd cmd;
1123 fe_status_t tunerstat; 1125 fe_status_t tunerstat;
1124 int i, status, ret, retune = 1; 1126 int i, status, ret, retune;
1125 1127
1126 dprintk("%s()\n",__func__); 1128 dprintk("%s()\n",__func__);
1127 1129
1128 state->dnxt.modulation = c->modulation;
1129 state->dnxt.frequency = c->frequency;
1130
1131 switch(c->delivery_system) { 1130 switch(c->delivery_system) {
1132 case SYS_DVBS: 1131 case SYS_DVBS:
1133 dprintk("%s: DVB-S delivery system selected\n",__func__); 1132 dprintk("%s: DVB-S delivery system selected\n",__func__);
1134 state->dnxt.pilot = PILOT_OFF; 1133
1134 /* Only QPSK is supported for DVB-S */
1135 if(c->modulation != QPSK) {
1136 dprintk("%s: unsupported modulation selected (%d)\n",
1137 __func__, c->modulation);
1138 return -EOPNOTSUPP;
1139 }
1140
1141 /* Pilot doesn't exist in DVB-S, turn bit off */
1142 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1143 retune = 1;
1144
1145 /* DVB-S only supports 0.35 */
1146 if(c->rolloff != ROLLOFF_35) {
1147 dprintk("%s: unsupported rolloff selected (%d)\n",
1148 __func__, c->rolloff);
1149 return -EOPNOTSUPP;
1150 }
1135 state->dnxt.rolloff_val = CX24116_ROLLOFF_035; 1151 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1136 state->dnxt.rolloff = c->rolloff;
1137 break; 1152 break;
1153
1138 case SYS_DVBS2: 1154 case SYS_DVBS2:
1139 dprintk("%s: DVB-S2 delivery system selected\n",__func__); 1155 dprintk("%s: DVB-S2 delivery system selected\n",__func__);
1140 if(c->pilot == PILOT_AUTO) 1156
1141 retune++; 1157 /*
1142 state->dnxt.pilot = c->pilot; 1158 * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
1159 * but not hardware auto detection
1160 */
1161 if(c->modulation != _8PSK && c->modulation != NBC_QPSK) {
1162 dprintk("%s: unsupported modulation selected (%d)\n",
1163 __func__, c->modulation);
1164 return -EOPNOTSUPP;
1165 }
1166
1167 switch(c->pilot) {
1168 case PILOT_AUTO: /* Not supported but emulated */
1169 retune = 2; /* Fall-through */
1170 case PILOT_OFF:
1171 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1172 break;
1173 case PILOT_ON:
1174 state->dnxt.pilot_val = CX24116_PILOT_ON;
1175 break;
1176 default:
1177 dprintk("%s: unsupported pilot mode selected (%d)\n",
1178 __func__, c->pilot);
1179 return -EOPNOTSUPP;
1180 }
1181
1143 switch(c->rolloff) { 1182 switch(c->rolloff) {
1144 case ROLLOFF_20: 1183 case ROLLOFF_20:
1145 state->dnxt.rolloff_val= CX24116_ROLLOFF_020; 1184 state->dnxt.rolloff_val= CX24116_ROLLOFF_020;
@@ -1150,20 +1189,28 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
1150 case ROLLOFF_35: 1189 case ROLLOFF_35:
1151 state->dnxt.rolloff_val= CX24116_ROLLOFF_035; 1190 state->dnxt.rolloff_val= CX24116_ROLLOFF_035;
1152 break; 1191 break;
1153 case ROLLOFF_AUTO: 1192 case ROLLOFF_AUTO: /* Rolloff must be explicit */
1193 default:
1194 dprintk("%s: unsupported rolloff selected (%d)\n",
1195 __func__, c->rolloff);
1154 return -EOPNOTSUPP; 1196 return -EOPNOTSUPP;
1155 } 1197 }
1156 state->dnxt.rolloff = c->rolloff;
1157 break; 1198 break;
1199
1158 default: 1200 default:
1159 dprintk("%s: unsupported delivery system selected (%d)\n", 1201 dprintk("%s: unsupported delivery system selected (%d)\n",
1160 __func__, c->delivery_system); 1202 __func__, c->delivery_system);
1161 return -EOPNOTSUPP; 1203 return -EOPNOTSUPP;
1162 } 1204 }
1205 state->dnxt.modulation = c->modulation;
1206 state->dnxt.frequency = c->frequency;
1207 state->dnxt.pilot = c->pilot;
1208 state->dnxt.rolloff = c->rolloff;
1163 1209
1164 if ((ret = cx24116_set_inversion(state, c->inversion)) != 0) 1210 if ((ret = cx24116_set_inversion(state, c->inversion)) != 0)
1165 return ret; 1211 return ret;
1166 1212
1213 /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1167 if ((ret = cx24116_set_fec(state, c->modulation, c->fec_inner)) != 0) 1214 if ((ret = cx24116_set_fec(state, c->modulation, c->fec_inner)) != 0)
1168 return ret; 1215 return ret;
1169 1216
@@ -1173,10 +1220,13 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
1173 /* discard the 'current' tuning parameters and prepare to tune */ 1220 /* discard the 'current' tuning parameters and prepare to tune */
1174 cx24116_clone_params(fe); 1221 cx24116_clone_params(fe);
1175 1222
1176 dprintk("%s: retune = %d\n", __func__, retune); 1223 dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation);
1177 dprintk("%s: rolloff = %d\n", __func__, state->dcur.rolloff);
1178 dprintk("%s: pilot = %d\n", __func__, state->dcur.pilot);
1179 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency); 1224 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
1225 dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__,
1226 state->dcur.pilot, state->dcur.pilot_val);
1227 dprintk("%s: retune = %d\n", __func__, retune);
1228 dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__,
1229 state->dcur.rolloff, state->dcur.rolloff_val);
1180 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate); 1230 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1181 dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__, 1231 dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
1182 state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val); 1232 state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
@@ -1210,11 +1260,8 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
1210 /* Automatic Inversion */ 1260 /* Automatic Inversion */
1211 cmd.args[0x06] = state->dcur.inversion_val; 1261 cmd.args[0x06] = state->dcur.inversion_val;
1212 1262
1213 /* Modulation / FEC & Pilot Off */ 1263 /* Modulation / FEC / Pilot */
1214 cmd.args[0x07] = state->dcur.fec_val; 1264 cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
1215
1216 if (state->dcur.pilot == PILOT_ON)
1217 cmd.args[0x07] |= CX24116_PILOT;
1218 1265
1219 cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8; 1266 cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
1220 cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff; 1267 cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
@@ -1277,7 +1324,7 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
1277 1324
1278 /* Toggle pilot bit when in auto-pilot */ 1325 /* Toggle pilot bit when in auto-pilot */
1279 if(state->dcur.pilot == PILOT_AUTO) 1326 if(state->dcur.pilot == PILOT_AUTO)
1280 cmd.args[0x07] ^= CX24116_PILOT; 1327 cmd.args[0x07] ^= CX24116_PILOT_ON;
1281 } 1328 }
1282 while(--retune); 1329 while(--retune);
1283 1330