Commit b6e760f3097501e60e76fbcb7a313d42da930c1f
Committed by
Mauro Carvalho Chehab
1 parent
fc27f04698
Exists in
master
and in
39 other branches
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>
Showing 4 changed files with 247 additions and 15 deletions Side-by-side Diff
drivers/media/dvb/dvb-core/dvb_frontend.c
... | ... | @@ -850,6 +850,49 @@ |
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", |
... | ... | @@ -949,6 +992,43 @@ |
949 | 992 | .cmd = DTV_TRANSMISSION_MODE, |
950 | 993 | .set = 1, |
951 | 994 | }, |
995 | + | |
996 | + _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0), | |
997 | + _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0), | |
998 | + _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0), | |
999 | + _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0), | |
1000 | + _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0), | |
1001 | + _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0), | |
1002 | + _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0), | |
1003 | + _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0), | |
1004 | + _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0), | |
1005 | + _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0), | |
1006 | + _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0), | |
1007 | + _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0), | |
1008 | + _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0), | |
1009 | + _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0), | |
1010 | + _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0), | |
1011 | + _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0), | |
1012 | + _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0), | |
1013 | + | |
1014 | + _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0), | |
1015 | + _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0), | |
1016 | + _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0), | |
1017 | + _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0), | |
1018 | + _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0), | |
1019 | + _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0), | |
1020 | + _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0), | |
1021 | + _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0), | |
1022 | + _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0), | |
1023 | + _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0), | |
1024 | + _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0), | |
1025 | + _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0), | |
1026 | + _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0), | |
1027 | + _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0), | |
1028 | + _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0), | |
1029 | + _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0), | |
1030 | + _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0), | |
1031 | + | |
952 | 1032 | /* Get */ |
953 | 1033 | [DTV_DISEQC_SLAVE_REPLY] = { |
954 | 1034 | .name = "DTV_DISEQC_SLAVE_REPLY", |
... | ... | @@ -956,6 +1036,7 @@ |
956 | 1036 | .set = 0, |
957 | 1037 | .buffer = 1, |
958 | 1038 | }, |
1039 | + | |
959 | 1040 | [DTV_API_VERSION] = { |
960 | 1041 | .name = "DTV_API_VERSION", |
961 | 1042 | .cmd = DTV_API_VERSION, |
962 | 1043 | |
963 | 1044 | |
... | ... | @@ -1165,14 +1246,21 @@ |
1165 | 1246 | if(c->delivery_system == SYS_ISDBT) { |
1166 | 1247 | /* Fake out a generic DVB-T request so we pass validation in the ioctl */ |
1167 | 1248 | p->frequency = c->frequency; |
1168 | - p->inversion = INVERSION_AUTO; | |
1249 | + p->inversion = c->inversion; | |
1169 | 1250 | p->u.ofdm.constellation = QAM_AUTO; |
1170 | 1251 | p->u.ofdm.code_rate_HP = FEC_AUTO; |
1171 | 1252 | p->u.ofdm.code_rate_LP = FEC_AUTO; |
1172 | - p->u.ofdm.bandwidth = BANDWIDTH_AUTO; | |
1173 | 1253 | p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; |
1174 | 1254 | p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; |
1175 | 1255 | p->u.ofdm.hierarchy_information = HIERARCHY_AUTO; |
1256 | + if (c->bandwidth_hz == 8000000) | |
1257 | + p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; | |
1258 | + else if (c->bandwidth_hz == 7000000) | |
1259 | + p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; | |
1260 | + else if (c->bandwidth_hz == 6000000) | |
1261 | + p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; | |
1262 | + else | |
1263 | + p->u.ofdm.bandwidth = BANDWIDTH_AUTO; | |
1176 | 1264 | } |
1177 | 1265 | } |
1178 | 1266 | |
... | ... | @@ -1274,6 +1362,59 @@ |
1274 | 1362 | case DTV_HIERARCHY: |
1275 | 1363 | tvp->u.data = fe->dtv_property_cache.hierarchy; |
1276 | 1364 | break; |
1365 | + | |
1366 | + /* ISDB-T Support here */ | |
1367 | + case DTV_ISDBT_PARTIAL_RECEPTION: | |
1368 | + tvp->u.data = fe->dtv_property_cache.isdbt_partial_reception; | |
1369 | + break; | |
1370 | + case DTV_ISDBT_SOUND_BROADCASTING: | |
1371 | + tvp->u.data = fe->dtv_property_cache.isdbt_sb_mode; | |
1372 | + break; | |
1373 | + case DTV_ISDBT_SB_SUBCHANNEL_ID: | |
1374 | + tvp->u.data = fe->dtv_property_cache.isdbt_sb_subchannel; | |
1375 | + break; | |
1376 | + case DTV_ISDBT_SB_SEGMENT_IDX: | |
1377 | + tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_idx; | |
1378 | + break; | |
1379 | + case DTV_ISDBT_SB_SEGMENT_COUNT: | |
1380 | + tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_count; | |
1381 | + break; | |
1382 | + case DTV_ISDBT_LAYERA_FEC: | |
1383 | + tvp->u.data = fe->dtv_property_cache.layer[0].fec; | |
1384 | + break; | |
1385 | + case DTV_ISDBT_LAYERA_MODULATION: | |
1386 | + tvp->u.data = fe->dtv_property_cache.layer[0].modulation; | |
1387 | + break; | |
1388 | + case DTV_ISDBT_LAYERA_SEGMENT_COUNT: | |
1389 | + tvp->u.data = fe->dtv_property_cache.layer[0].segment_count; | |
1390 | + break; | |
1391 | + case DTV_ISDBT_LAYERA_TIME_INTERLEAVING: | |
1392 | + tvp->u.data = fe->dtv_property_cache.layer[0].interleaving; | |
1393 | + break; | |
1394 | + case DTV_ISDBT_LAYERB_FEC: | |
1395 | + tvp->u.data = fe->dtv_property_cache.layer[1].fec; | |
1396 | + break; | |
1397 | + case DTV_ISDBT_LAYERB_MODULATION: | |
1398 | + tvp->u.data = fe->dtv_property_cache.layer[1].modulation; | |
1399 | + break; | |
1400 | + case DTV_ISDBT_LAYERB_SEGMENT_COUNT: | |
1401 | + tvp->u.data = fe->dtv_property_cache.layer[1].segment_count; | |
1402 | + break; | |
1403 | + case DTV_ISDBT_LAYERB_TIME_INTERLEAVING: | |
1404 | + tvp->u.data = fe->dtv_property_cache.layer[1].interleaving; | |
1405 | + break; | |
1406 | + case DTV_ISDBT_LAYERC_FEC: | |
1407 | + tvp->u.data = fe->dtv_property_cache.layer[2].fec; | |
1408 | + break; | |
1409 | + case DTV_ISDBT_LAYERC_MODULATION: | |
1410 | + tvp->u.data = fe->dtv_property_cache.layer[2].modulation; | |
1411 | + break; | |
1412 | + case DTV_ISDBT_LAYERC_SEGMENT_COUNT: | |
1413 | + tvp->u.data = fe->dtv_property_cache.layer[2].segment_count; | |
1414 | + break; | |
1415 | + case DTV_ISDBT_LAYERC_TIME_INTERLEAVING: | |
1416 | + tvp->u.data = fe->dtv_property_cache.layer[2].interleaving; | |
1417 | + break; | |
1277 | 1418 | default: |
1278 | 1419 | r = -1; |
1279 | 1420 | } |
1280 | 1421 | |
... | ... | @@ -1302,10 +1443,8 @@ |
1302 | 1443 | /* Reset a cache of data specific to the frontend here. This does |
1303 | 1444 | * not effect hardware. |
1304 | 1445 | */ |
1446 | + dvb_frontend_clear_cache(fe); | |
1305 | 1447 | dprintk("%s() Flushing property cache\n", __func__); |
1306 | - memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties)); | |
1307 | - fe->dtv_property_cache.state = tvp->cmd; | |
1308 | - fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; | |
1309 | 1448 | break; |
1310 | 1449 | case DTV_TUNE: |
1311 | 1450 | /* interpret the cache of data, build either a traditional frontend |
... | ... | @@ -1370,6 +1509,59 @@ |
1370 | 1509 | break; |
1371 | 1510 | case DTV_HIERARCHY: |
1372 | 1511 | fe->dtv_property_cache.hierarchy = tvp->u.data; |
1512 | + break; | |
1513 | + | |
1514 | + /* ISDB-T Support here */ | |
1515 | + case DTV_ISDBT_PARTIAL_RECEPTION: | |
1516 | + fe->dtv_property_cache.isdbt_partial_reception = tvp->u.data; | |
1517 | + break; | |
1518 | + case DTV_ISDBT_SOUND_BROADCASTING: | |
1519 | + fe->dtv_property_cache.isdbt_sb_mode = tvp->u.data; | |
1520 | + break; | |
1521 | + case DTV_ISDBT_SB_SUBCHANNEL_ID: | |
1522 | + fe->dtv_property_cache.isdbt_sb_subchannel = tvp->u.data; | |
1523 | + break; | |
1524 | + case DTV_ISDBT_SB_SEGMENT_IDX: | |
1525 | + fe->dtv_property_cache.isdbt_sb_segment_idx = tvp->u.data; | |
1526 | + break; | |
1527 | + case DTV_ISDBT_SB_SEGMENT_COUNT: | |
1528 | + fe->dtv_property_cache.isdbt_sb_segment_count = tvp->u.data; | |
1529 | + break; | |
1530 | + case DTV_ISDBT_LAYERA_FEC: | |
1531 | + fe->dtv_property_cache.layer[0].fec = tvp->u.data; | |
1532 | + break; | |
1533 | + case DTV_ISDBT_LAYERA_MODULATION: | |
1534 | + fe->dtv_property_cache.layer[0].modulation = tvp->u.data; | |
1535 | + break; | |
1536 | + case DTV_ISDBT_LAYERA_SEGMENT_COUNT: | |
1537 | + fe->dtv_property_cache.layer[0].segment_count = tvp->u.data; | |
1538 | + break; | |
1539 | + case DTV_ISDBT_LAYERA_TIME_INTERLEAVING: | |
1540 | + fe->dtv_property_cache.layer[0].interleaving = tvp->u.data; | |
1541 | + break; | |
1542 | + case DTV_ISDBT_LAYERB_FEC: | |
1543 | + fe->dtv_property_cache.layer[1].fec = tvp->u.data; | |
1544 | + break; | |
1545 | + case DTV_ISDBT_LAYERB_MODULATION: | |
1546 | + fe->dtv_property_cache.layer[1].modulation = tvp->u.data; | |
1547 | + break; | |
1548 | + case DTV_ISDBT_LAYERB_SEGMENT_COUNT: | |
1549 | + fe->dtv_property_cache.layer[1].segment_count = tvp->u.data; | |
1550 | + break; | |
1551 | + case DTV_ISDBT_LAYERB_TIME_INTERLEAVING: | |
1552 | + fe->dtv_property_cache.layer[1].interleaving = tvp->u.data; | |
1553 | + break; | |
1554 | + case DTV_ISDBT_LAYERC_FEC: | |
1555 | + fe->dtv_property_cache.layer[2].fec = tvp->u.data; | |
1556 | + break; | |
1557 | + case DTV_ISDBT_LAYERC_MODULATION: | |
1558 | + fe->dtv_property_cache.layer[2].modulation = tvp->u.data; | |
1559 | + break; | |
1560 | + case DTV_ISDBT_LAYERC_SEGMENT_COUNT: | |
1561 | + fe->dtv_property_cache.layer[2].segment_count = tvp->u.data; | |
1562 | + break; | |
1563 | + case DTV_ISDBT_LAYERC_TIME_INTERLEAVING: | |
1564 | + fe->dtv_property_cache.layer[2].interleaving = tvp->u.data; | |
1373 | 1565 | break; |
1374 | 1566 | default: |
1375 | 1567 | r = -1; |
drivers/media/dvb/dvb-core/dvb_frontend.h
... | ... | @@ -341,6 +341,20 @@ |
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 { |
include/linux/dvb/frontend.h
... | ... | @@ -173,7 +173,8 @@ |
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 { |
180 | 181 | |
... | ... | @@ -268,15 +269,40 @@ |
268 | 269 | #define DTV_FE_CAPABILITY 16 |
269 | 270 | #define DTV_DELIVERY_SYSTEM 17 |
270 | 271 | |
271 | -#define DTV_API_VERSION 35 | |
272 | -#define DTV_API_VERSION 35 | |
273 | -#define DTV_CODE_RATE_HP 36 | |
274 | -#define DTV_CODE_RATE_LP 37 | |
275 | -#define DTV_GUARD_INTERVAL 38 | |
276 | -#define DTV_TRANSMISSION_MODE 39 | |
277 | -#define DTV_HIERARCHY 40 | |
272 | +/* ISDB-T and ISDB-Tsb */ | |
273 | +#define DTV_ISDBT_PARTIAL_RECEPTION 18 | |
274 | +#define DTV_ISDBT_SOUND_BROADCASTING 19 | |
278 | 275 | |
279 | -#define DTV_MAX_COMMAND DTV_HIERARCHY | |
276 | +#define DTV_ISDBT_SB_SUBCHANNEL_ID 20 | |
277 | +#define DTV_ISDBT_SB_SEGMENT_IDX 21 | |
278 | +#define DTV_ISDBT_SB_SEGMENT_COUNT 22 | |
279 | + | |
280 | +#define DTV_ISDBT_LAYERA_FEC 23 | |
281 | +#define DTV_ISDBT_LAYERA_MODULATION 24 | |
282 | +#define DTV_ISDBT_LAYERA_SEGMENT_COUNT 25 | |
283 | +#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING 26 | |
284 | + | |
285 | +#define DTV_ISDBT_LAYERB_FEC 27 | |
286 | +#define DTV_ISDBT_LAYERB_MODULATION 28 | |
287 | +#define DTV_ISDBT_LAYERB_SEGMENT_COUNT 29 | |
288 | +#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING 30 | |
289 | + | |
290 | +#define DTV_ISDBT_LAYERC_FEC 31 | |
291 | +#define DTV_ISDBT_LAYERC_MODULATION 32 | |
292 | +#define DTV_ISDBT_LAYERC_SEGMENT_COUNT 33 | |
293 | +#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING 34 | |
294 | + | |
295 | +#define DTV_API_VERSION 35 | |
296 | + | |
297 | +#define DTV_CODE_RATE_HP 36 | |
298 | +#define DTV_CODE_RATE_LP 37 | |
299 | +#define DTV_GUARD_INTERVAL 38 | |
300 | +#define DTV_TRANSMISSION_MODE 39 | |
301 | +#define DTV_HIERARCHY 40 | |
302 | + | |
303 | +#define DTV_ISDBT_LAYER_ENABLED 41 | |
304 | + | |
305 | +#define DTV_MAX_COMMAND DTV_ISDBT_LAYER_ENABLED | |
280 | 306 | |
281 | 307 | typedef enum fe_pilot { |
282 | 308 | PILOT_ON, |