aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/tdmb/tcc3170/src/tcc_fic_decoder/tcc_fic_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/tdmb/tcc3170/src/tcc_fic_decoder/tcc_fic_decoder.c')
-rw-r--r--drivers/media/tdmb/tcc3170/src/tcc_fic_decoder/tcc_fic_decoder.c540
1 files changed, 0 insertions, 540 deletions
diff --git a/drivers/media/tdmb/tcc3170/src/tcc_fic_decoder/tcc_fic_decoder.c b/drivers/media/tdmb/tcc3170/src/tcc_fic_decoder/tcc_fic_decoder.c
deleted file mode 100644
index 8997c44..0000000
--- a/drivers/media/tdmb/tcc3170/src/tcc_fic_decoder/tcc_fic_decoder.c
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * tcc_fic_decoder.c
- *
- * Author: <linux@telechips.com>
- * Description: Telechips broadcast driver
- *
- * Copyright (c) Telechips, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "tcc_fic_decoder.h"
-
-/******************************************************************************
-* UEP Table
-* +---------------+-----------+-----------------------------------+
-* |Bit rate(4bits)|Protect Lv | SubCh Size(9bits) |
-* |---------------|---+---+---|---+---+---+---+---+---+---+---+---|
-* | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x | x |
-* +---------------+-----------+-----------------------------------+
-*
-*******************************************************************************/
-static const unsigned short uep_table[64] = {
- 0x0810, 0x0615, 0x0418, 0x021d, 0x0023, 0x1818, 0x161d, 0x1423,
- 0x122a, 0x1034, 0x281d, 0x2623, 0x242a, 0x2234, 0x3820, 0x362a,
- 0x3430, 0x323a, 0x3046, 0x4828, 0x4634, 0x443a, 0x4246, 0x4054,
- 0x5830, 0x563a, 0x5446, 0x5254, 0x5068, 0x683a, 0x6646, 0x6454,
- 0x6268, 0x7840, 0x7654, 0x7460, 0x7274, 0x708c, 0x8850, 0x8668,
- 0x8474, 0x828c, 0x80a8, 0x9860, 0x9674, 0x948c, 0x92a8, 0x90d0,
- 0xa874, 0xa68c, 0xa4a8, 0xa2d0, 0xa0e8, 0xb880, 0xb6a8, 0xb4c0,
- 0xb2e8, 0xb118, 0xc8a0, 0xc6d0, 0xc318, 0xd8c0, 0xd518, 0xd1a0 };
-
-static struct fic_parser_matadata parser_metadata;
-static struct tcc_ensemble_info user_ensbl_info;
-
-static s32 parsing_fig0(struct fic_parser_matadata *fic_info,
- u8 *fig_buff, s32 length)
-{
- s32 ret = FICERR_SUCCESS;
- u8 extension;
-
- fic_info->fig_cn = (*fig_buff & 0x80) >> 7;
- fic_info->fig_oe0 = (*fig_buff & 0x40) >> 6;
- fic_info->fig_pd = (*fig_buff & 0x20) >> 5;
- extension = (*fig_buff++ & 0x1f);
-
- length--;
- /* service link FIG */
- if ((extension != 6) && (extension != 21) && (extension != 24)) {
- if (fic_info->fig_cn) {
- if (fic_info->reconf_stage) {
- if (extension > 0)
- return FICERR_FIG0_NEXT_FIG;
- } else {
- return FICERR_FIG0_NEXT_FIG1;
- }
- }
- }
-
- switch (extension) {
- case EXT_00:
- ret = fig0_ext00(fic_info, fig_buff, length);
- break;
- case EXT_01:
- ret = fig0_ext01(fic_info, fig_buff, length);
- break;
- case EXT_02:
- ret = fig0_ext02(fic_info, fig_buff, length);
- break;
- case EXT_03:
- ret = fig0_ext03(fic_info, fig_buff, length);
- break;
- case EXT_04:
- ret = fig0_ext04(fic_info, fig_buff, length);
- break;
- case EXT_05:
- ret = fig0_ext05(fic_info, fig_buff, length);
- break;
- case EXT_08:
- ret = fig0_ext08(fic_info, fig_buff, length);
- break;
- case EXT_13:
- ret = fig0_ext13(fic_info, fig_buff, length);
- break;
- case EXT_17:
- ret = fig0_ext17(fic_info, fig_buff, length);
- break;
- default:
- break;
- }
- return ret;
-}
-
-
-static s32 parsing_fig1(
- struct fic_parser_matadata *fic_info,
- u8 *fig_buff,
- s32 length)
-{
- s32 ret;
- u8 extension, charset;
-
- fic_info->fig_oe1 = (*fig_buff & 0x08) >> 3;
-
- if (fic_info->fig_oe1 != 0)
- return FICERR_FIG_NODATA;
-
- charset = (*fig_buff & 0xf0) >> 4;
- extension = (*fig_buff++ & 0x07);
- length--;
- switch (extension) {
- case EXT_00:
- ret = fig1_ext00(fic_info, fig_buff, length, charset);
- break;
- case EXT_01:
- ret = fig1_ext01(fic_info, fig_buff, length, charset);
- break;
- case EXT_04:
- ret = fig1_ext04(fic_info, fig_buff, length, charset);
- break;
- case EXT_05:
- ret = fig1_ext05(fic_info, fig_buff, length, charset);
- break;
- case EXT_06:
- ret = fig1_ext06(fic_info, fig_buff, length, charset);
- default:
- break;
- }
-
- return FICERR_SUCCESS;
-}
-
-static u32 fic_channel_updated(void)
-{
- u32 i, j;
- u32 num_svc, num_svc_comp, num_subch;
-
- struct fic_parser_matadata *metadata = &parser_metadata;
- struct tcc_ensemble *esmbl = &metadata->esmbl_start;
- struct tcc_service *svc = metadata->svc_start;
- struct tcc_service_comp *svc_comp = metadata->svc_comp_start;
- struct tcc_user_app_types *user_app = metadata->user_app_start;
-
- num_svc = esmbl->num_svc;
- num_svc_comp = esmbl->num_svc_comp;
- num_subch = esmbl->num_svc_comp;
-
- if (!num_svc_comp)
- return CH_UPDATE_NO_DATA;
-
- if (!num_subch)
- return CH_UPDATE_NO_DATA;
-
- if (esmbl->label[0] == 0x00)
- return CH_UPDATE_NO_DATA;
-
- if (num_svc) {
- for (i = 0; i < num_svc; i++) {
- if ((svc + i)->svc_label[0] == 0)
- return CH_UPDATE_NO_DATA;
- }
- } else {
- return CH_UPDATE_NO_DATA;
- }
-
- for (i = 0; i < num_svc_comp; i++) {
- if ((svc_comp + i)->fidc_id == 0xff)
- return CH_UPDATE_NO_DATA;
- }
-
- for (i = 0; i < num_svc_comp; i++) {
- if (svc_comp[i].tmid == 3 || svc_comp[i].ascty_dscty == 5) {
- if (svc_comp[i].ascty_dscty == 0)
- return CH_UPDATE_ESSENTIAL_DATA;
-
- for (j = 0; j < num_svc_comp; j++) {
- if (svc_comp[i].sid == user_app[j].sid &&
- svc_comp[i].scids == user_app[j].scids)
- break;
- }
- if (j == num_svc_comp)
- return CH_UPDATE_ESSENTIAL_DATA;
-
- if (svc_comp[i].scids == 0x0f)
- return CH_UPDATE_ESSENTIAL_DATA;
- }
-
- if (svc_comp[i].order) {
- if ((svc_comp + i)->label[0] == 0)
- return CH_UPDATE_ESSENTIAL_DATA;
- }
- }
-
- return CH_UPDATE_FULL_DATA;
-}
-
-void tcc_fic_parser_init(void)
-{
- s32 i;
- struct fic_parser_matadata *metadata;
-
- metadata = &parser_metadata;
- memset(metadata, 0, sizeof(parser_metadata));
-
- metadata->reconf_stage = 0;
- metadata->fig_cn = 0;
- metadata->fig_oe0 = 0;
- metadata->fig_pd = 0;
- metadata->fig_oe1 = 0;
- metadata->fib_cnt = 0;
-
- for (i = 0; i < NUM_SVC_COMP; i++)
- metadata->svc_comp_start[i].scids = 0x0f;
-
- for (i = 0; i < NUM_USER_APP; i++)
- metadata->user_app_start[i].scids = 0x0f;
-}
-
-static s32 fib_decode(u8 *fig_buff)
-{
- s32 ret = FICERR_SUCCESS;
- struct fic_parser_matadata *fic_info;
-
- s32 fig_len;
- u32 fig_type;
- u32 buff_point = 0;
- s32 buff_len = 30;
-
- fic_info = &parser_metadata;
-
- if (ret != FICERR_SUCCESS)
- return ret;
-
- /* the size of FIG is bigger than 2bytes */
- while (buff_len > 0) {
- /* find a FIG header */
- if (*(fig_buff + buff_point) == 0xff ||
- *(fig_buff + buff_point) == 0x00) {
- ret = FICERR_FIBD_ENDMARKER;
- break;
- }
-
- fig_type = (*(fig_buff + buff_point) & 0xe0) >> 5;
- fig_len = (*(fig_buff + buff_point) & 0x1f);
- if (fig_len > 29 || fig_len == 0)
- return FICERR_FIBD_INVALID_LENGTH;
-
- buff_point++;
- if (fig_len <= 0x01) {
- ret = FICERR_FIG_NODATA;
- return ret;
- }
-
- switch (fig_type) {
- case FIG0:
- ret = parsing_fig0(fic_info,
- fig_buff + buff_point, fig_len);
- break;
- case FIG1:
- ret = parsing_fig1(fic_info,
- fig_buff+buff_point, fig_len);
- break;
- default:
- ret = FICERR_FIBD_UNKNOWN_FIGTYPE;
- return ret;
- }
-
- buff_point += fig_len;
- buff_len -= (fig_len + 1);
- }
-
- if (buff_len < 0)
- ret = FICERR_FIBD_INVALID_LENGTH;
- return ret;
-}
-
-static u16 fib_crc16(u8 *buf)
-{
- u32 b, len;
- u8 crcl, crcm;
-
- crcl = 0xff;
- crcm = 0xff;
-
-
- for (len = 0; len < 30; len++) {
- b = *(buf + len) ^ crcm;
- b = b ^ (b >> 4);
- crcm = crcl ^ (b >> 3) ^ (b << 4);
- crcl = b ^ (b << 5);
- }
-
- crcl = crcl ^ 0xff;
- crcm = crcm ^ 0xff;
- return (u16)crcl | ((u16)crcm << 8);
-}
-
-
-static void fic_copy_sub_ch(struct fic_parser_matadata *fic_info,
- struct tcc_service_comp_info *svc_comp_info)
-{
- s32 i;
- struct tcc_ensemble *esbl = &fic_info->esmbl_start;
- struct tcc_sub_channel *subch_start = fic_info->subch_start;
-
- for (i = 0; i < esbl->num_svc_comp; i++) {
- if (svc_comp_info->svc_comp.fidc_id != subch_start[i].subch_id)
- continue;
- memcpy(&svc_comp_info->sub_ch, &subch_start[i],
- sizeof(struct tcc_sub_channel));
- break;
- }
-}
-
-static void fic_copy_svc_comp(struct fic_parser_matadata *fic_info,
- struct tcc_service_info *svc_info)
-{
- s32 i, j = 0;
- struct tcc_ensemble *esbl = &fic_info->esmbl_start;
- struct tcc_service_comp *src_svc_comp = fic_info->svc_comp_start;
- struct tcc_service_comp_info *svc_comp_info;
-
- for (i = 0; i < esbl->num_svc_comp; i++) {
- if (svc_info->svc.sid != src_svc_comp[i].sid)
- continue;
- svc_comp_info = &svc_info->svc_comp_info[j];
- memcpy(&svc_comp_info->svc_comp, &src_svc_comp[i],
- sizeof(struct tcc_service_comp));
- fic_copy_sub_ch(fic_info, svc_comp_info);
- j++;
- }
-}
-
-struct tcc_service_comp_info *tcc_fic_get_svc_comp_info(s32 _subch_id)
-{
- s32 i;
- struct tcc_service_comp_info *svc_comp_info;
- struct tcc_ensemble *ensbl = &user_ensbl_info.ensbl;
- struct tcc_service_info *svc_info = user_ensbl_info.svc_info;
-
- for (i = 0; i < ensbl->num_svc_comp; i++) {
- svc_comp_info = &svc_info[i].svc_comp_info[0];
- if (svc_comp_info->svc_comp.fidc_id == _subch_id)
- return svc_comp_info;
- }
- return NULL;
-}
-
-u8 tcc_fic_get_ptype(struct tcc_service_comp_info *svc_comp_info)
-{
- struct tcc_sub_channel *sub_ch = &svc_comp_info->sub_ch;
- if (sub_ch->form_flag & 0x08)
- return 1;
- else
- return 0;
-}
-
-u8 tcc_fic_get_plevel(struct tcc_service_comp_info *svc_comp_info)
-{
- u8 eep8[4] = {0, 1, 2, 3};
- u8 eep32[4] = {4, 5, 6, 7};
- u8 opt, protect;
- struct tcc_sub_channel *sub_ch = &svc_comp_info->sub_ch;
-
- if (sub_ch->form_flag & 0x08) {
- opt = (sub_ch->form_flag & 0x04) ? 1 : 0;
- protect = sub_ch->form_flag & 0x03;
- if (opt)
- return eep32[protect];
- else
- return eep8[protect];
- } else {
- return (uep_table[sub_ch->tbl_index] & 0x0E00) >> 9;
- }
-}
-
-u16 tcc_fic_get_cu_size(struct tcc_service_comp_info *svc_comp_info)
-{
- struct tcc_sub_channel *sub_ch = &svc_comp_info->sub_ch;
-
- if (sub_ch->form_flag & 0x08)
- return sub_ch->size_cu;
- else
- return uep_table[sub_ch->tbl_index] & 0x1FF;
-}
-
-u16 tcc_fic_get_cu_start(struct tcc_service_comp_info *svc_comp_info)
-{
- struct tcc_sub_channel *sub_ch = &svc_comp_info->sub_ch;
-
- return sub_ch->size_cu;
-}
-
-u8 tcc_fic_get_subch_id(struct tcc_service_comp_info *svc_comp_info)
-{
- struct tcc_sub_channel *sub_ch = &svc_comp_info->sub_ch;
-
- return sub_ch->subch_id;
-}
-
-
-u8 tcc_fic_get_bitrate(struct tcc_service_comp_info *svc_comp_info)
-{
- u8 opt, protect;
- struct tcc_sub_channel *sub_ch = &svc_comp_info->sub_ch;
-
- if ((sub_ch->form_flag & 0x08) == 0)
- return (uep_table[sub_ch->tbl_index] & 0xf000) >> 12;
-
- opt = (sub_ch->form_flag & 0x04) ? 1 : 0;
- protect = sub_ch->form_flag & 0x03;
- if (opt) {
- switch (protect) {
- case 0:
- return sub_ch->size_cu / 27;
- case 1:
- return sub_ch->size_cu / 21;
- case 2:
- return sub_ch->size_cu / 18;
- case 3:
- return sub_ch->size_cu / 15;
- default:
- return 0;
- }
- /*human readable bitrate is x32*/
- } else {
- switch (protect) {
- case 0:
- return sub_ch->size_cu / 12;
- case 1:
- return sub_ch->size_cu / 8;
- case 2:
- return sub_ch->size_cu / 6;
- case 3:
- return sub_ch->size_cu / 4;
- default:
- return 0;
- }
- /*human readable bitrate is x8*/
- }
-}
-
-u8 tcc_fic_get_rs(struct tcc_service_comp_info *svc_comp_info)
-{
- struct tcc_service_comp *svc_comp = &svc_comp_info->svc_comp;
- if (svc_comp->ascty_dscty == 0x18)
- return 1;
- else
- return 0;
-}
-
-/**
-* @param buff buffer for fic
-* @param size fic buffer size. it must be 384 bytes.
-* @return -1 : invalid argument, 0 : in progress, > 0 : parsing done
-*/
-s32 tcc_fic_run_decoder(u8 *buff, s32 size)
-{
- s32 cnt = 0, ret = 0;
- s32 num_broken_fib = 0;
- u16 fib_crc;
-
- if ((size%TCC_FIB_SIZE) != 0) {
- tcbd_debug(DEBUG_ERROR, "invalid fic size:%d!\n", size);
- return -1;
- }
- while (size > cnt * TCC_FIB_SIZE) {
- fib_crc = (u16)(buff[(cnt * TCC_FIB_SIZE) + 30] << 8) |
- (u16)buff[(cnt * TCC_FIB_SIZE) + 31];
- if (fib_crc != fib_crc16(buff + (cnt * TCC_FIB_SIZE))) {
- num_broken_fib++;
- tcbd_debug(DEBUG_ERROR, "broken fib cnt:%d\n", cnt);
- goto cont_loop;
- }
- fib_decode(buff + (cnt * TCC_FIB_SIZE));
- ret = fic_channel_updated();
- if (ret == CH_UPDATE_ESSENTIAL_DATA ||
- ret == CH_UPDATE_FULL_DATA) {
- break;
- }
-cont_loop:
- cnt++;
- }
- return ret;
-}
-
-void tcc_fic_disp_ensbl_info(struct tcc_ensemble_info *ensbl_info)
-{
- s32 i, j;
- struct tcc_ensemble *esbl = &ensbl_info->ensbl;
- struct tcc_service_info *svc_info;
- struct tcc_service_comp_info *svc_comp_info;
-
- tcbd_debug(DEBUG_INFO, "[ %s ] %d services available!\n",
- esbl->label, esbl->num_svc);
- for (i = 0; i < esbl->num_svc; i++) {
- svc_info = &ensbl_info->svc_info[i];
- tcbd_debug(DEBUG_INFO, " => [ %s ] %d service component\n",
- svc_info->svc.svc_label,
- svc_info->svc.num_svc_comp);
- for (j = 0; j < svc_info->svc.num_svc_comp; j++) {
- svc_comp_info = &svc_info->svc_comp_info[j];
- tcbd_debug(DEBUG_INFO, " -> sub channel id [%d]\n",
- svc_comp_info[j].svc_comp.fidc_id);
- }
- }
-}
-
-struct tcc_ensemble_info *tcc_fic_get_ensbl_info(s32 _disp)
-{
- s32 i;
- struct fic_parser_matadata *fic_info = &parser_metadata;
- struct tcc_ensemble *esbl = &fic_info->esmbl_start;
- struct tcc_service *svc = fic_info->svc_start;
- struct tcc_service_info *svc_info;
-
- memcpy(&user_ensbl_info.ensbl, esbl, sizeof(struct tcc_ensemble));
- for (i = 0; i < esbl->num_svc; i++) {
- svc_info = &user_ensbl_info.svc_info[i];
- memcpy(&svc_info->svc, &svc[i], sizeof(struct tcc_service));
- fic_copy_svc_comp(fic_info, svc_info);
- }
-
- if (_disp)
- tcc_fic_disp_ensbl_info(&user_ensbl_info);
-
- return &user_ensbl_info;
-}
-