Commit b6e760f3097501e60e76fbcb7a313d42da930c1f

Authored by Patrick Boettcher
Committed by Mauro Carvalho Chehab
1 parent fc27f04698

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,
include/linux/dvb/version.h
... ... @@ -24,7 +24,7 @@
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_*/