diff options
-rw-r--r-- | drivers/media/dvb/frontends/cx24116.c | 89 |
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 | ||