Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (12892): DVB-API: add support for ISDB-T and ISDB-Tsb (version 5.1)

This patch increments the DVB-API to version 5.1 in order to reflect the addition of ISDB-T and ISDB-Tsb on Linux' DVB-API.

Changes in detail:
- added a small document to describe how to use the API to tune to an ISDB-T or ISDB-Tsb channel
- added necessary fields to dtv_frontend_cache
- added a smarter clear-cache function which resets all fields of the dtv_frontend_cache
- added a TRANSMISSION_MODE_4K to fe_transmit_mode_t

Signed-off-by: Olivier Grenie <olgrenie@dibcom.fr>
Signed-off-by: Patrick Boettcher <pboettcher@dibcom.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Patrick Boettcher and committed by
Mauro Carvalho Chehab
b6e760f3 fc27f046

+247 -15
+197 -5
drivers/media/dvb/dvb-core/dvb_frontend.c
··· 850 850 return 0; 851 851 } 852 852 853 + static int dvb_frontend_clear_cache(struct dvb_frontend *fe) 854 + { 855 + int i; 856 + 857 + memset(&(fe->dtv_property_cache), 0, 858 + sizeof(struct dtv_frontend_properties)); 859 + 860 + fe->dtv_property_cache.state = DTV_CLEAR; 861 + fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; 862 + fe->dtv_property_cache.inversion = INVERSION_AUTO; 863 + fe->dtv_property_cache.fec_inner = FEC_AUTO; 864 + fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO; 865 + fe->dtv_property_cache.bandwidth_hz = BANDWIDTH_AUTO; 866 + fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO; 867 + fe->dtv_property_cache.hierarchy = HIERARCHY_AUTO; 868 + fe->dtv_property_cache.symbol_rate = QAM_AUTO; 869 + fe->dtv_property_cache.code_rate_HP = FEC_AUTO; 870 + fe->dtv_property_cache.code_rate_LP = FEC_AUTO; 871 + 872 + fe->dtv_property_cache.isdbt_partial_reception = -1; 873 + fe->dtv_property_cache.isdbt_sb_mode = -1; 874 + fe->dtv_property_cache.isdbt_sb_subchannel = -1; 875 + fe->dtv_property_cache.isdbt_sb_segment_idx = -1; 876 + fe->dtv_property_cache.isdbt_sb_segment_count = -1; 877 + fe->dtv_property_cache.isdbt_layer_enabled = 0x7; 878 + for (i = 0; i < 3; i++) { 879 + fe->dtv_property_cache.layer[i].fec = FEC_AUTO; 880 + fe->dtv_property_cache.layer[i].modulation = QAM_AUTO; 881 + fe->dtv_property_cache.layer[i].interleaving = -1; 882 + fe->dtv_property_cache.layer[i].segment_count = -1; 883 + } 884 + 885 + return 0; 886 + } 887 + 888 + #define _DTV_CMD(n, s, b) \ 889 + [n] = { \ 890 + .name = #n, \ 891 + .cmd = n, \ 892 + .set = s,\ 893 + .buffer = b \ 894 + } 895 + 853 896 static struct dtv_cmds_h dtv_cmds[] = { 854 897 [DTV_TUNE] = { 855 898 .name = "DTV_TUNE", ··· 992 949 .cmd = DTV_TRANSMISSION_MODE, 993 950 .set = 1, 994 951 }, 952 + 953 + _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0), 954 + _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0), 955 + _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0), 956 + _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0), 957 + _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0), 958 + _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0), 959 + _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0), 960 + _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0), 961 + _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0), 962 + _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0), 963 + _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0), 964 + _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0), 965 + _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0), 966 + _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0), 967 + _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0), 968 + _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0), 969 + _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0), 970 + 971 + _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0), 972 + _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0), 973 + _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0), 974 + _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0), 975 + _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0), 976 + _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0), 977 + _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0), 978 + _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0), 979 + _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0), 980 + _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0), 981 + _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0), 982 + _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0), 983 + _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0), 984 + _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0), 985 + _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0), 986 + _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0), 987 + _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0), 988 + 995 989 /* Get */ 996 990 [DTV_DISEQC_SLAVE_REPLY] = { 997 991 .name = "DTV_DISEQC_SLAVE_REPLY", ··· 1036 956 .set = 0, 1037 957 .buffer = 1, 1038 958 }, 959 + 1039 960 [DTV_API_VERSION] = { 1040 961 .name = "DTV_API_VERSION", 1041 962 .cmd = DTV_API_VERSION, ··· 1246 1165 if(c->delivery_system == SYS_ISDBT) { 1247 1166 /* Fake out a generic DVB-T request so we pass validation in the ioctl */ 1248 1167 p->frequency = c->frequency; 1249 - p->inversion = INVERSION_AUTO; 1168 + p->inversion = c->inversion; 1250 1169 p->u.ofdm.constellation = QAM_AUTO; 1251 1170 p->u.ofdm.code_rate_HP = FEC_AUTO; 1252 1171 p->u.ofdm.code_rate_LP = FEC_AUTO; 1253 - p->u.ofdm.bandwidth = BANDWIDTH_AUTO; 1254 1172 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; 1255 1173 p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; 1256 1174 p->u.ofdm.hierarchy_information = HIERARCHY_AUTO; 1175 + if (c->bandwidth_hz == 8000000) 1176 + p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; 1177 + else if (c->bandwidth_hz == 7000000) 1178 + p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; 1179 + else if (c->bandwidth_hz == 6000000) 1180 + p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; 1181 + else 1182 + p->u.ofdm.bandwidth = BANDWIDTH_AUTO; 1257 1183 } 1258 1184 } 1259 1185 ··· 1362 1274 case DTV_HIERARCHY: 1363 1275 tvp->u.data = fe->dtv_property_cache.hierarchy; 1364 1276 break; 1277 + 1278 + /* ISDB-T Support here */ 1279 + case DTV_ISDBT_PARTIAL_RECEPTION: 1280 + tvp->u.data = fe->dtv_property_cache.isdbt_partial_reception; 1281 + break; 1282 + case DTV_ISDBT_SOUND_BROADCASTING: 1283 + tvp->u.data = fe->dtv_property_cache.isdbt_sb_mode; 1284 + break; 1285 + case DTV_ISDBT_SB_SUBCHANNEL_ID: 1286 + tvp->u.data = fe->dtv_property_cache.isdbt_sb_subchannel; 1287 + break; 1288 + case DTV_ISDBT_SB_SEGMENT_IDX: 1289 + tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_idx; 1290 + break; 1291 + case DTV_ISDBT_SB_SEGMENT_COUNT: 1292 + tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_count; 1293 + break; 1294 + case DTV_ISDBT_LAYERA_FEC: 1295 + tvp->u.data = fe->dtv_property_cache.layer[0].fec; 1296 + break; 1297 + case DTV_ISDBT_LAYERA_MODULATION: 1298 + tvp->u.data = fe->dtv_property_cache.layer[0].modulation; 1299 + break; 1300 + case DTV_ISDBT_LAYERA_SEGMENT_COUNT: 1301 + tvp->u.data = fe->dtv_property_cache.layer[0].segment_count; 1302 + break; 1303 + case DTV_ISDBT_LAYERA_TIME_INTERLEAVING: 1304 + tvp->u.data = fe->dtv_property_cache.layer[0].interleaving; 1305 + break; 1306 + case DTV_ISDBT_LAYERB_FEC: 1307 + tvp->u.data = fe->dtv_property_cache.layer[1].fec; 1308 + break; 1309 + case DTV_ISDBT_LAYERB_MODULATION: 1310 + tvp->u.data = fe->dtv_property_cache.layer[1].modulation; 1311 + break; 1312 + case DTV_ISDBT_LAYERB_SEGMENT_COUNT: 1313 + tvp->u.data = fe->dtv_property_cache.layer[1].segment_count; 1314 + break; 1315 + case DTV_ISDBT_LAYERB_TIME_INTERLEAVING: 1316 + tvp->u.data = fe->dtv_property_cache.layer[1].interleaving; 1317 + break; 1318 + case DTV_ISDBT_LAYERC_FEC: 1319 + tvp->u.data = fe->dtv_property_cache.layer[2].fec; 1320 + break; 1321 + case DTV_ISDBT_LAYERC_MODULATION: 1322 + tvp->u.data = fe->dtv_property_cache.layer[2].modulation; 1323 + break; 1324 + case DTV_ISDBT_LAYERC_SEGMENT_COUNT: 1325 + tvp->u.data = fe->dtv_property_cache.layer[2].segment_count; 1326 + break; 1327 + case DTV_ISDBT_LAYERC_TIME_INTERLEAVING: 1328 + tvp->u.data = fe->dtv_property_cache.layer[2].interleaving; 1329 + break; 1365 1330 default: 1366 1331 r = -1; 1367 1332 } ··· 1443 1302 /* Reset a cache of data specific to the frontend here. This does 1444 1303 * not effect hardware. 1445 1304 */ 1305 + dvb_frontend_clear_cache(fe); 1446 1306 dprintk("%s() Flushing property cache\n", __func__); 1447 - memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties)); 1448 - fe->dtv_property_cache.state = tvp->cmd; 1449 - fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; 1450 1307 break; 1451 1308 case DTV_TUNE: 1452 1309 /* interpret the cache of data, build either a traditional frontend ··· 1509 1370 break; 1510 1371 case DTV_HIERARCHY: 1511 1372 fe->dtv_property_cache.hierarchy = tvp->u.data; 1373 + break; 1374 + 1375 + /* ISDB-T Support here */ 1376 + case DTV_ISDBT_PARTIAL_RECEPTION: 1377 + fe->dtv_property_cache.isdbt_partial_reception = tvp->u.data; 1378 + break; 1379 + case DTV_ISDBT_SOUND_BROADCASTING: 1380 + fe->dtv_property_cache.isdbt_sb_mode = tvp->u.data; 1381 + break; 1382 + case DTV_ISDBT_SB_SUBCHANNEL_ID: 1383 + fe->dtv_property_cache.isdbt_sb_subchannel = tvp->u.data; 1384 + break; 1385 + case DTV_ISDBT_SB_SEGMENT_IDX: 1386 + fe->dtv_property_cache.isdbt_sb_segment_idx = tvp->u.data; 1387 + break; 1388 + case DTV_ISDBT_SB_SEGMENT_COUNT: 1389 + fe->dtv_property_cache.isdbt_sb_segment_count = tvp->u.data; 1390 + break; 1391 + case DTV_ISDBT_LAYERA_FEC: 1392 + fe->dtv_property_cache.layer[0].fec = tvp->u.data; 1393 + break; 1394 + case DTV_ISDBT_LAYERA_MODULATION: 1395 + fe->dtv_property_cache.layer[0].modulation = tvp->u.data; 1396 + break; 1397 + case DTV_ISDBT_LAYERA_SEGMENT_COUNT: 1398 + fe->dtv_property_cache.layer[0].segment_count = tvp->u.data; 1399 + break; 1400 + case DTV_ISDBT_LAYERA_TIME_INTERLEAVING: 1401 + fe->dtv_property_cache.layer[0].interleaving = tvp->u.data; 1402 + break; 1403 + case DTV_ISDBT_LAYERB_FEC: 1404 + fe->dtv_property_cache.layer[1].fec = tvp->u.data; 1405 + break; 1406 + case DTV_ISDBT_LAYERB_MODULATION: 1407 + fe->dtv_property_cache.layer[1].modulation = tvp->u.data; 1408 + break; 1409 + case DTV_ISDBT_LAYERB_SEGMENT_COUNT: 1410 + fe->dtv_property_cache.layer[1].segment_count = tvp->u.data; 1411 + break; 1412 + case DTV_ISDBT_LAYERB_TIME_INTERLEAVING: 1413 + fe->dtv_property_cache.layer[1].interleaving = tvp->u.data; 1414 + break; 1415 + case DTV_ISDBT_LAYERC_FEC: 1416 + fe->dtv_property_cache.layer[2].fec = tvp->u.data; 1417 + break; 1418 + case DTV_ISDBT_LAYERC_MODULATION: 1419 + fe->dtv_property_cache.layer[2].modulation = tvp->u.data; 1420 + break; 1421 + case DTV_ISDBT_LAYERC_SEGMENT_COUNT: 1422 + fe->dtv_property_cache.layer[2].segment_count = tvp->u.data; 1423 + break; 1424 + case DTV_ISDBT_LAYERC_TIME_INTERLEAVING: 1425 + fe->dtv_property_cache.layer[2].interleaving = tvp->u.data; 1512 1426 break; 1513 1427 default: 1514 1428 r = -1;
+14
drivers/media/dvb/dvb-core/dvb_frontend.h
··· 341 341 fe_rolloff_t rolloff; 342 342 343 343 fe_delivery_system_t delivery_system; 344 + 345 + /* ISDB-T specifics */ 346 + u8 isdbt_partial_reception; 347 + u8 isdbt_sb_mode; 348 + u8 isdbt_sb_subchannel; 349 + u32 isdbt_sb_segment_idx; 350 + u32 isdbt_sb_segment_count; 351 + u8 isdbt_layer_enabled; 352 + struct { 353 + u8 segment_count; 354 + fe_code_rate_t fec; 355 + fe_modulation_t modulation; 356 + u8 interleaving; 357 + } layer[3]; 344 358 }; 345 359 346 360 struct dvb_frontend {
+35 -9
include/linux/dvb/frontend.h
··· 173 173 typedef enum fe_transmit_mode { 174 174 TRANSMISSION_MODE_2K, 175 175 TRANSMISSION_MODE_8K, 176 - TRANSMISSION_MODE_AUTO 176 + TRANSMISSION_MODE_AUTO, 177 + TRANSMISSION_MODE_4K 177 178 } fe_transmit_mode_t; 178 179 179 180 typedef enum fe_bandwidth { ··· 269 268 #define DTV_FE_CAPABILITY 16 270 269 #define DTV_DELIVERY_SYSTEM 17 271 270 272 - #define DTV_API_VERSION 35 273 - #define DTV_API_VERSION 35 274 - #define DTV_CODE_RATE_HP 36 275 - #define DTV_CODE_RATE_LP 37 276 - #define DTV_GUARD_INTERVAL 38 277 - #define DTV_TRANSMISSION_MODE 39 278 - #define DTV_HIERARCHY 40 271 + /* ISDB-T and ISDB-Tsb */ 272 + #define DTV_ISDBT_PARTIAL_RECEPTION 18 273 + #define DTV_ISDBT_SOUND_BROADCASTING 19 279 274 280 - #define DTV_MAX_COMMAND DTV_HIERARCHY 275 + #define DTV_ISDBT_SB_SUBCHANNEL_ID 20 276 + #define DTV_ISDBT_SB_SEGMENT_IDX 21 277 + #define DTV_ISDBT_SB_SEGMENT_COUNT 22 278 + 279 + #define DTV_ISDBT_LAYERA_FEC 23 280 + #define DTV_ISDBT_LAYERA_MODULATION 24 281 + #define DTV_ISDBT_LAYERA_SEGMENT_COUNT 25 282 + #define DTV_ISDBT_LAYERA_TIME_INTERLEAVING 26 283 + 284 + #define DTV_ISDBT_LAYERB_FEC 27 285 + #define DTV_ISDBT_LAYERB_MODULATION 28 286 + #define DTV_ISDBT_LAYERB_SEGMENT_COUNT 29 287 + #define DTV_ISDBT_LAYERB_TIME_INTERLEAVING 30 288 + 289 + #define DTV_ISDBT_LAYERC_FEC 31 290 + #define DTV_ISDBT_LAYERC_MODULATION 32 291 + #define DTV_ISDBT_LAYERC_SEGMENT_COUNT 33 292 + #define DTV_ISDBT_LAYERC_TIME_INTERLEAVING 34 293 + 294 + #define DTV_API_VERSION 35 295 + 296 + #define DTV_CODE_RATE_HP 36 297 + #define DTV_CODE_RATE_LP 37 298 + #define DTV_GUARD_INTERVAL 38 299 + #define DTV_TRANSMISSION_MODE 39 300 + #define DTV_HIERARCHY 40 301 + 302 + #define DTV_ISDBT_LAYER_ENABLED 41 303 + 304 + #define DTV_MAX_COMMAND DTV_ISDBT_LAYER_ENABLED 281 305 282 306 typedef enum fe_pilot { 283 307 PILOT_ON,
+1 -1
include/linux/dvb/version.h
··· 24 24 #define _DVBVERSION_H_ 25 25 26 26 #define DVB_API_VERSION 5 27 - #define DVB_API_VERSION_MINOR 0 27 + #define DVB_API_VERSION_MINOR 1 28 28 29 29 #endif /*_DVBVERSION_H_*/