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 | ||
