aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/common
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/Kconfig22
-rw-r--r--drivers/media/common/Makefile4
-rw-r--r--drivers/media/common/b2c2/Kconfig5
-rw-r--r--drivers/media/common/b2c2/flexcop-fe-tuner.c4
-rw-r--r--drivers/media/common/b2c2/flexcop-sram.c6
-rw-r--r--drivers/media/common/btcx-risc.c260
-rw-r--r--drivers/media/common/btcx-risc.h34
-rw-r--r--drivers/media/common/cx2341x.c1726
-rw-r--r--drivers/media/common/cypress_firmware.c132
-rw-r--r--drivers/media/common/cypress_firmware.h28
-rw-r--r--drivers/media/common/saa7146/saa7146_core.c4
-rw-r--r--drivers/media/common/saa7146/saa7146_fops.c5
-rw-r--r--drivers/media/common/saa7146/saa7146_video.c27
-rw-r--r--drivers/media/common/siano/Kconfig28
-rw-r--r--drivers/media/common/siano/Makefile11
-rw-r--r--drivers/media/common/siano/sms-cards.c115
-rw-r--r--drivers/media/common/siano/sms-cards.h14
-rw-r--r--drivers/media/common/siano/smscoreapi.c1299
-rw-r--r--drivers/media/common/siano/smscoreapi.h1007
-rw-r--r--drivers/media/common/siano/smsdvb-debugfs.c551
-rw-r--r--drivers/media/common/siano/smsdvb-main.c1232
-rw-r--r--drivers/media/common/siano/smsdvb.c1078
-rw-r--r--drivers/media/common/siano/smsdvb.h130
-rw-r--r--drivers/media/common/siano/smsendian.c44
-rw-r--r--drivers/media/common/siano/smsir.c2
-rw-r--r--drivers/media/common/siano/smsir.h10
-rw-r--r--drivers/media/common/tveeprom.c776
27 files changed, 6707 insertions, 1847 deletions
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index 121b0110af3..b85f88c8ddb 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -1,3 +1,25 @@
+# Used by common drivers, when they need to ask questions
+config MEDIA_COMMON_OPTIONS
+ bool
+
+comment "common driver options"
+ depends on MEDIA_COMMON_OPTIONS
+
+config VIDEO_CX2341X
+ tristate
+
+config VIDEO_BTCX
+ depends on PCI
+ tristate
+
+config VIDEO_TVEEPROM
+ tristate
+ depends on I2C
+
+config CYPRESS_FIRMWARE
+ tristate "Cypress firmware helper routines"
+ depends on USB
+
source "drivers/media/common/b2c2/Kconfig"
source "drivers/media/common/saa7146/Kconfig"
source "drivers/media/common/siano/Kconfig"
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index b8e2e3a33a3..d208de3b7cc 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1 +1,5 @@
obj-y += b2c2/ saa7146/ siano/
+obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
+obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
+obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
+obj-$(CONFIG_CYPRESS_FIRMWARE) += cypress_firmware.o
diff --git a/drivers/media/common/b2c2/Kconfig b/drivers/media/common/b2c2/Kconfig
index 1df9e578daa..a8c6cdfaa2f 100644
--- a/drivers/media/common/b2c2/Kconfig
+++ b/drivers/media/common/b2c2/Kconfig
@@ -17,11 +17,6 @@ config DVB_B2C2_FLEXCOP
select DVB_CX24123 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
select DVB_TUNER_CX24113 if MEDIA_SUBDRV_AUTOSELECT
- help
- Support for the digital TV receiver chip made by B2C2 Inc. included in
- Technisats PCI cards and USB boxes.
-
- Say Y if you own such a device and want to use it.
# Selected via the PCI or USB flexcop drivers
config DVB_B2C2_FLEXCOP_DEBUG
diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c
index 850a6c60675..7e14e90d292 100644
--- a/drivers/media/common/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/common/b2c2/flexcop-fe-tuner.c
@@ -325,7 +325,7 @@ static int skystar2_rev27_attach(struct flexcop_device *fc,
/* enable no_base_addr - no repeated start when reading */
fc->fc_i2c_adap[2].no_base_addr = 1;
if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
- 0x08, 1, 1)) {
+ 0x08, 1, 1, false)) {
err("ISL6421 could NOT be attached");
goto fail_isl;
}
@@ -391,7 +391,7 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
fc->fc_i2c_adap[2].no_base_addr = 1;
if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
- 0x08, 0, 0)) {
+ 0x08, 0, 0, false)) {
err("ISL6421 could NOT be attached");
fc->fc_i2c_adap[2].no_base_addr = 0;
return 0;
diff --git a/drivers/media/common/b2c2/flexcop-sram.c b/drivers/media/common/b2c2/flexcop-sram.c
index f2199e43e80..185c285f70f 100644
--- a/drivers/media/common/b2c2/flexcop-sram.c
+++ b/drivers/media/common/b2c2/flexcop-sram.c
@@ -85,7 +85,7 @@ static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *
while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
mdelay(1);
retries--;
- };
+ }
if (retries == 0)
printk("%s: SRAM timeout\n", __func__);
@@ -110,7 +110,7 @@ static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf,
while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
mdelay(1);
retries--;
- };
+ }
if (retries == 0)
printk("%s: SRAM timeout\n", __func__);
@@ -122,7 +122,7 @@ static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf,
while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
mdelay(1);
retries--;
- };
+ }
if (retries == 0)
printk("%s: SRAM timeout\n", __func__);
diff --git a/drivers/media/common/btcx-risc.c b/drivers/media/common/btcx-risc.c
new file mode 100644
index 00000000000..ac1b2687a20
--- /dev/null
+++ b/drivers/media/common/btcx-risc.c
@@ -0,0 +1,260 @@
+/*
+
+ btcx-risc.c
+
+ bt848/bt878/cx2388x risc code generator.
+
+ (c) 2000-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/videodev2.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+#include "btcx-risc.h"
+
+MODULE_DESCRIPTION("some code shared by bttv and cx88xx drivers");
+MODULE_AUTHOR("Gerd Knorr");
+MODULE_LICENSE("GPL");
+
+static unsigned int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug,"debug messages, default is 0 (no)");
+
+/* ---------------------------------------------------------- */
+/* allocate/free risc memory */
+
+static int memcnt;
+
+void btcx_riscmem_free(struct pci_dev *pci,
+ struct btcx_riscmem *risc)
+{
+ if (NULL == risc->cpu)
+ return;
+ if (debug) {
+ memcnt--;
+ printk("btcx: riscmem free [%d] dma=%lx\n",
+ memcnt, (unsigned long)risc->dma);
+ }
+ pci_free_consistent(pci, risc->size, risc->cpu, risc->dma);
+ memset(risc,0,sizeof(*risc));
+}
+
+int btcx_riscmem_alloc(struct pci_dev *pci,
+ struct btcx_riscmem *risc,
+ unsigned int size)
+{
+ __le32 *cpu;
+ dma_addr_t dma = 0;
+
+ if (NULL != risc->cpu && risc->size < size)
+ btcx_riscmem_free(pci,risc);
+ if (NULL == risc->cpu) {
+ cpu = pci_alloc_consistent(pci, size, &dma);
+ if (NULL == cpu)
+ return -ENOMEM;
+ risc->cpu = cpu;
+ risc->dma = dma;
+ risc->size = size;
+ if (debug) {
+ memcnt++;
+ printk("btcx: riscmem alloc [%d] dma=%lx cpu=%p size=%d\n",
+ memcnt, (unsigned long)dma, cpu, size);
+ }
+ }
+ memset(risc->cpu,0,risc->size);
+ return 0;
+}
+
+/* ---------------------------------------------------------- */
+/* screen overlay helpers */
+
+int
+btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
+ struct v4l2_clip *clips, unsigned int n)
+{
+ if (win->left < 0) {
+ /* left */
+ clips[n].c.left = 0;
+ clips[n].c.top = 0;
+ clips[n].c.width = -win->left;
+ clips[n].c.height = win->height;
+ n++;
+ }
+ if (win->left + win->width > swidth) {
+ /* right */
+ clips[n].c.left = swidth - win->left;
+ clips[n].c.top = 0;
+ clips[n].c.width = win->width - clips[n].c.left;
+ clips[n].c.height = win->height;
+ n++;
+ }
+ if (win->top < 0) {
+ /* top */
+ clips[n].c.left = 0;
+ clips[n].c.top = 0;
+ clips[n].c.width = win->width;
+ clips[n].c.height = -win->top;
+ n++;
+ }
+ if (win->top + win->height > sheight) {
+ /* bottom */
+ clips[n].c.left = 0;
+ clips[n].c.top = sheight - win->top;
+ clips[n].c.width = win->width;
+ clips[n].c.height = win->height - clips[n].c.top;
+ n++;
+ }
+ return n;
+}
+
+int
+btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int mask)
+{
+ s32 nx,nw,dx;
+ unsigned int i;
+
+ /* fixup window */
+ nx = (win->left + mask) & ~mask;
+ nw = (win->width) & ~mask;
+ if (nx + nw > win->left + win->width)
+ nw -= mask+1;
+ dx = nx - win->left;
+ win->left = nx;
+ win->width = nw;
+ if (debug)
+ printk(KERN_DEBUG "btcx: window align %dx%d+%d+%d [dx=%d]\n",
+ win->width, win->height, win->left, win->top, dx);
+
+ /* fixup clips */
+ for (i = 0; i < n; i++) {
+ nx = (clips[i].c.left-dx) & ~mask;
+ nw = (clips[i].c.width) & ~mask;
+ if (nx + nw < clips[i].c.left-dx + clips[i].c.width)
+ nw += mask+1;
+ clips[i].c.left = nx;
+ clips[i].c.width = nw;
+ if (debug)
+ printk(KERN_DEBUG "btcx: clip align %dx%d+%d+%d\n",
+ clips[i].c.width, clips[i].c.height,
+ clips[i].c.left, clips[i].c.top);
+ }
+ return 0;
+}
+
+void
+btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips)
+{
+ struct v4l2_clip swap;
+ int i,j,n;
+
+ if (nclips < 2)
+ return;
+ for (i = nclips-2; i >= 0; i--) {
+ for (n = 0, j = 0; j <= i; j++) {
+ if (clips[j].c.left > clips[j+1].c.left) {
+ swap = clips[j];
+ clips[j] = clips[j+1];
+ clips[j+1] = swap;
+ n++;
+ }
+ }
+ if (0 == n)
+ break;
+ }
+}
+
+void
+btcx_calc_skips(int line, int width, int *maxy,
+ struct btcx_skiplist *skips, unsigned int *nskips,
+ const struct v4l2_clip *clips, unsigned int nclips)
+{
+ unsigned int clip,skip;
+ int end, maxline;
+
+ skip=0;
+ maxline = 9999;
+ for (clip = 0; clip < nclips; clip++) {
+
+ /* sanity checks */
+ if (clips[clip].c.left + clips[clip].c.width <= 0)
+ continue;
+ if (clips[clip].c.left > (signed)width)
+ break;
+
+ /* vertical range */
+ if (line > clips[clip].c.top+clips[clip].c.height-1)
+ continue;
+ if (line < clips[clip].c.top) {
+ if (maxline > clips[clip].c.top-1)
+ maxline = clips[clip].c.top-1;
+ continue;
+ }
+ if (maxline > clips[clip].c.top+clips[clip].c.height-1)
+ maxline = clips[clip].c.top+clips[clip].c.height-1;
+
+ /* horizontal range */
+ if (0 == skip || clips[clip].c.left > skips[skip-1].end) {
+ /* new one */
+ skips[skip].start = clips[clip].c.left;
+ if (skips[skip].start < 0)
+ skips[skip].start = 0;
+ skips[skip].end = clips[clip].c.left + clips[clip].c.width;
+ if (skips[skip].end > width)
+ skips[skip].end = width;
+ skip++;
+ } else {
+ /* overlaps -- expand last one */
+ end = clips[clip].c.left + clips[clip].c.width;
+ if (skips[skip-1].end < end)
+ skips[skip-1].end = end;
+ if (skips[skip-1].end > width)
+ skips[skip-1].end = width;
+ }
+ }
+ *nskips = skip;
+ *maxy = maxline;
+
+ if (debug) {
+ printk(KERN_DEBUG "btcx: skips line %d-%d:",line,maxline);
+ for (skip = 0; skip < *nskips; skip++) {
+ printk(" %d-%d",skips[skip].start,skips[skip].end);
+ }
+ printk("\n");
+ }
+}
+
+/* ---------------------------------------------------------- */
+
+EXPORT_SYMBOL(btcx_riscmem_alloc);
+EXPORT_SYMBOL(btcx_riscmem_free);
+
+EXPORT_SYMBOL(btcx_screen_clips);
+EXPORT_SYMBOL(btcx_align);
+EXPORT_SYMBOL(btcx_sort_clips);
+EXPORT_SYMBOL(btcx_calc_skips);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/common/btcx-risc.h b/drivers/media/common/btcx-risc.h
new file mode 100644
index 00000000000..f8bc6e8e7b5
--- /dev/null
+++ b/drivers/media/common/btcx-risc.h
@@ -0,0 +1,34 @@
+/*
+ */
+struct btcx_riscmem {
+ unsigned int size;
+ __le32 *cpu;
+ __le32 *jmp;
+ dma_addr_t dma;
+};
+
+struct btcx_skiplist {
+ int start;
+ int end;
+};
+
+int btcx_riscmem_alloc(struct pci_dev *pci,
+ struct btcx_riscmem *risc,
+ unsigned int size);
+void btcx_riscmem_free(struct pci_dev *pci,
+ struct btcx_riscmem *risc);
+
+int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win,
+ struct v4l2_clip *clips, unsigned int n);
+int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips,
+ unsigned int n, int mask);
+void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips);
+void btcx_calc_skips(int line, int width, int *maxy,
+ struct btcx_skiplist *skips, unsigned int *nskips,
+ const struct v4l2_clip *clips, unsigned int nclips);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/common/cx2341x.c b/drivers/media/common/cx2341x.c
new file mode 100644
index 00000000000..103ef6bad2e
--- /dev/null
+++ b/drivers/media/common/cx2341x.c
@@ -0,0 +1,1726 @@
+/*
+ * cx2341x - generic code for cx23415/6/8 based devices
+ *
+ * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+
+#include <media/tuner.h>
+#include <media/cx2341x.h>
+#include <media/v4l2-common.h>
+
+MODULE_DESCRIPTION("cx23415/6/8 driver");
+MODULE_AUTHOR("Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+/********************** COMMON CODE *********************/
+
+/* definitions for audio properties bits 29-28 */
+#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
+#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
+#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
+
+static const char *cx2341x_get_name(u32 id)
+{
+ switch (id) {
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+ return "Spatial Filter Mode";
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+ return "Spatial Filter";
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+ return "Spatial Luma Filter Type";
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+ return "Spatial Chroma Filter Type";
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+ return "Temporal Filter Mode";
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+ return "Temporal Filter";
+ case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+ return "Median Filter Type";
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+ return "Median Luma Filter Maximum";
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+ return "Median Luma Filter Minimum";
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+ return "Median Chroma Filter Maximum";
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+ return "Median Chroma Filter Minimum";
+ case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
+ return "Insert Navigation Packets";
+ }
+ return NULL;
+}
+
+static const char **cx2341x_get_menu(u32 id)
+{
+ static const char *cx2341x_video_spatial_filter_mode_menu[] = {
+ "Manual",
+ "Auto",
+ NULL
+ };
+
+ static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
+ "Off",
+ "1D Horizontal",
+ "1D Vertical",
+ "2D H/V Separable",
+ "2D Symmetric non-separable",
+ NULL
+ };
+
+ static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
+ "Off",
+ "1D Horizontal",
+ NULL
+ };
+
+ static const char *cx2341x_video_temporal_filter_mode_menu[] = {
+ "Manual",
+ "Auto",
+ NULL
+ };
+
+ static const char *cx2341x_video_median_filter_type_menu[] = {
+ "Off",
+ "Horizontal",
+ "Vertical",
+ "Horizontal/Vertical",
+ "Diagonal",
+ NULL
+ };
+
+ switch (id) {
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+ return cx2341x_video_spatial_filter_mode_menu;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+ return cx2341x_video_luma_spatial_filter_type_menu;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+ return cx2341x_video_chroma_spatial_filter_type_menu;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+ return cx2341x_video_temporal_filter_mode_menu;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+ return cx2341x_video_median_filter_type_menu;
+ }
+ return NULL;
+}
+
+static void cx2341x_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
+ s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags)
+{
+ *name = cx2341x_get_name(id);
+ *flags = 0;
+
+ switch (id) {
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+ *type = V4L2_CTRL_TYPE_MENU;
+ *min = 0;
+ *step = 0;
+ break;
+ case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
+ *type = V4L2_CTRL_TYPE_BOOLEAN;
+ *min = 0;
+ *max = *step = 1;
+ break;
+ default:
+ *type = V4L2_CTRL_TYPE_INTEGER;
+ break;
+ }
+ switch (id) {
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+ *flags |= V4L2_CTRL_FLAG_UPDATE;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+ *flags |= V4L2_CTRL_FLAG_SLIDER;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ *flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ break;
+ }
+}
+
+
+/********************** OLD CODE *********************/
+
+/* Must be sorted from low to high control ID! */
+const u32 cx2341x_mpeg_ctrls[] = {
+ V4L2_CID_MPEG_CLASS,
+ V4L2_CID_MPEG_STREAM_TYPE,
+ V4L2_CID_MPEG_STREAM_VBI_FMT,
+ V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
+ V4L2_CID_MPEG_AUDIO_ENCODING,
+ V4L2_CID_MPEG_AUDIO_L2_BITRATE,
+ V4L2_CID_MPEG_AUDIO_MODE,
+ V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
+ V4L2_CID_MPEG_AUDIO_EMPHASIS,
+ V4L2_CID_MPEG_AUDIO_CRC,
+ V4L2_CID_MPEG_AUDIO_MUTE,
+ V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
+ V4L2_CID_MPEG_VIDEO_ENCODING,
+ V4L2_CID_MPEG_VIDEO_ASPECT,
+ V4L2_CID_MPEG_VIDEO_B_FRAMES,
+ V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+ V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ V4L2_CID_MPEG_VIDEO_BITRATE,
+ V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+ V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
+ V4L2_CID_MPEG_VIDEO_MUTE,
+ V4L2_CID_MPEG_VIDEO_MUTE_YUV,
+ V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
+ V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
+ V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
+ V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
+ V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
+ V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
+ V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
+ V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
+ V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
+ V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
+ V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
+ V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
+ 0
+};
+EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
+
+static const struct cx2341x_mpeg_params default_params = {
+ /* misc */
+ .capabilities = 0,
+ .port = CX2341X_PORT_MEMORY,
+ .width = 720,
+ .height = 480,
+ .is_50hz = 0,
+
+ /* stream */
+ .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
+ .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
+ .stream_insert_nav_packets = 0,
+
+ /* audio */
+ .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
+ .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+ .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
+ .audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K,
+ .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
+ .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
+ .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
+ .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
+ .audio_mute = 0,
+
+ /* video */
+ .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
+ .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
+ .video_b_frames = 2,
+ .video_gop_size = 12,
+ .video_gop_closure = 1,
+ .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ .video_bitrate = 6000000,
+ .video_bitrate_peak = 8000000,
+ .video_temporal_decimation = 0,
+ .video_mute = 0,
+ .video_mute_yuv = 0x008080, /* YCbCr value for black */
+
+ /* encoding filters */
+ .video_spatial_filter_mode =
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
+ .video_spatial_filter = 0,
+ .video_luma_spatial_filter_type =
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
+ .video_chroma_spatial_filter_type =
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
+ .video_temporal_filter_mode =
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
+ .video_temporal_filter = 8,
+ .video_median_filter_type =
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
+ .video_luma_median_filter_top = 255,
+ .video_luma_median_filter_bottom = 0,
+ .video_chroma_median_filter_top = 255,
+ .video_chroma_median_filter_bottom = 0,
+};
+/* Map the control ID to the correct field in the cx2341x_mpeg_params
+ struct. Return -EINVAL if the ID is unknown, else return 0. */
+static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
+ struct v4l2_ext_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ ctrl->value = params->audio_sampling_freq;
+ break;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ ctrl->value = params->audio_encoding;
+ break;
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ ctrl->value = params->audio_l2_bitrate;
+ break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ ctrl->value = params->audio_ac3_bitrate;
+ break;
+ case V4L2_CID_MPEG_AUDIO_MODE:
+ ctrl->value = params->audio_mode;
+ break;
+ case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
+ ctrl->value = params->audio_mode_extension;
+ break;
+ case V4L2_CID_MPEG_AUDIO_EMPHASIS:
+ ctrl->value = params->audio_emphasis;
+ break;
+ case V4L2_CID_MPEG_AUDIO_CRC:
+ ctrl->value = params->audio_crc;
+ break;
+ case V4L2_CID_MPEG_AUDIO_MUTE:
+ ctrl->value = params->audio_mute;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ ctrl->value = params->video_encoding;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ ctrl->value = params->video_aspect;
+ break;
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ ctrl->value = params->video_b_frames;
+ break;
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ ctrl->value = params->video_gop_size;
+ break;
+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+ ctrl->value = params->video_gop_closure;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ ctrl->value = params->video_bitrate_mode;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ ctrl->value = params->video_bitrate;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ ctrl->value = params->video_bitrate_peak;
+ break;
+ case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
+ ctrl->value = params->video_temporal_decimation;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MUTE:
+ ctrl->value = params->video_mute;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
+ ctrl->value = params->video_mute_yuv;
+ break;
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ ctrl->value = params->stream_type;
+ break;
+ case V4L2_CID_MPEG_STREAM_VBI_FMT:
+ ctrl->value = params->stream_vbi_fmt;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+ ctrl->value = params->video_spatial_filter_mode;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+ ctrl->value = params->video_spatial_filter;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+ ctrl->value = params->video_luma_spatial_filter_type;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+ ctrl->value = params->video_chroma_spatial_filter_type;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+ ctrl->value = params->video_temporal_filter_mode;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+ ctrl->value = params->video_temporal_filter;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+ ctrl->value = params->video_median_filter_type;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+ ctrl->value = params->video_luma_median_filter_top;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+ ctrl->value = params->video_luma_median_filter_bottom;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+ ctrl->value = params->video_chroma_median_filter_top;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+ ctrl->value = params->video_chroma_median_filter_bottom;
+ break;
+ case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
+ ctrl->value = params->stream_insert_nav_packets;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/* Map the control ID to the correct field in the cx2341x_mpeg_params
+ struct. Return -EINVAL if the ID is unknown, else return 0. */
+static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
+ struct v4l2_ext_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ if (busy)
+ return -EBUSY;
+ params->audio_sampling_freq = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (busy)
+ return -EBUSY;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3)
+ if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
+ ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
+ return -ERANGE;
+ params->audio_encoding = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ if (busy)
+ return -EBUSY;
+ params->audio_l2_bitrate = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (busy)
+ return -EBUSY;
+ if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
+ return -EINVAL;
+ params->audio_ac3_bitrate = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_AUDIO_MODE:
+ params->audio_mode = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
+ params->audio_mode_extension = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_AUDIO_EMPHASIS:
+ params->audio_emphasis = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_AUDIO_CRC:
+ params->audio_crc = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_AUDIO_MUTE:
+ params->audio_mute = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ params->video_aspect = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
+ int b = ctrl->value + 1;
+ int gop = params->video_gop_size;
+ params->video_b_frames = ctrl->value;
+ params->video_gop_size = b * ((gop + b - 1) / b);
+ /* Max GOP size = 34 */
+ while (params->video_gop_size > 34)
+ params->video_gop_size -= b;
+ break;
+ }
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
+ int b = params->video_b_frames + 1;
+ int gop = ctrl->value;
+ params->video_gop_size = b * ((gop + b - 1) / b);
+ /* Max GOP size = 34 */
+ while (params->video_gop_size > 34)
+ params->video_gop_size -= b;
+ ctrl->value = params->video_gop_size;
+ break;
+ }
+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+ params->video_gop_closure = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ if (busy)
+ return -EBUSY;
+ /* MPEG-1 only allows CBR */
+ if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
+ ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+ return -EINVAL;
+ params->video_bitrate_mode = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ if (busy)
+ return -EBUSY;
+ params->video_bitrate = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ if (busy)
+ return -EBUSY;
+ params->video_bitrate_peak = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
+ params->video_temporal_decimation = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_VIDEO_MUTE:
+ params->video_mute = (ctrl->value != 0);
+ break;
+ case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
+ params->video_mute_yuv = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ if (busy)
+ return -EBUSY;
+ params->stream_type = ctrl->value;
+ params->video_encoding =
+ (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
+ params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1 :
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+ if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
+ /* MPEG-1 implies CBR */
+ params->video_bitrate_mode =
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
+ break;
+ case V4L2_CID_MPEG_STREAM_VBI_FMT:
+ params->stream_vbi_fmt = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+ params->video_spatial_filter_mode = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+ params->video_spatial_filter = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+ params->video_luma_spatial_filter_type = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+ params->video_chroma_spatial_filter_type = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+ params->video_temporal_filter_mode = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+ params->video_temporal_filter = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+ params->video_median_filter_type = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+ params->video_luma_median_filter_top = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+ params->video_luma_median_filter_bottom = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+ params->video_chroma_median_filter_top = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+ params->video_chroma_median_filter_bottom = ctrl->value;
+ break;
+ case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
+ params->stream_insert_nav_packets = ctrl->value;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl,
+ s32 min, s32 max, s32 step, s32 def)
+{
+ const char *name;
+
+ switch (qctrl->id) {
+ /* MPEG controls */
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+ case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
+ cx2341x_ctrl_fill(qctrl->id, &name, &qctrl->type,
+ &min, &max, &step, &def, &qctrl->flags);
+ qctrl->minimum = min;
+ qctrl->maximum = max;
+ qctrl->step = step;
+ qctrl->default_value = def;
+ qctrl->reserved[0] = qctrl->reserved[1] = 0;
+ strlcpy(qctrl->name, name, sizeof(qctrl->name));
+ return 0;
+
+ default:
+ return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
+ }
+}
+
+int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
+ struct v4l2_queryctrl *qctrl)
+{
+ int err;
+
+ switch (qctrl->id) {
+ case V4L2_CID_MPEG_CLASS:
+ return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
+
+ case V4L2_CID_MPEG_STREAM_VBI_FMT:
+ if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE,
+ V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE);
+ return cx2341x_ctrl_query_fill(qctrl,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
+ default_params.stream_vbi_fmt);
+
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
+
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+ /*
+ * The state of L2 & AC3 bitrate controls can change
+ * when this control changes, but v4l2_ctrl_query_fill()
+ * already sets V4L2_CTRL_FLAG_UPDATE for
+ * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
+ */
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+ V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
+ default_params.audio_encoding);
+ }
+
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
+ default_params.audio_encoding);
+
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_L2_BITRATE_192K,
+ V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
+ default_params.audio_l2_bitrate);
+ if (err)
+ return err;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
+ params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
+
+ case V4L2_CID_MPEG_AUDIO_MODE:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_MODE_STEREO,
+ V4L2_MPEG_AUDIO_MODE_MONO, 1,
+ V4L2_MPEG_AUDIO_MODE_STEREO);
+
+ case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
+ if (err == 0 &&
+ params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return err;
+
+ case V4L2_CID_MPEG_AUDIO_EMPHASIS:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_EMPHASIS_NONE,
+ V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
+ V4L2_MPEG_AUDIO_EMPHASIS_NONE);
+
+ case V4L2_CID_MPEG_AUDIO_CRC:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_CRC_NONE,
+ V4L2_MPEG_AUDIO_CRC_CRC16, 1,
+ V4L2_MPEG_AUDIO_CRC_NONE);
+
+ case V4L2_CID_MPEG_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
+
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
+ default_params.audio_ac3_bitrate);
+ if (err)
+ return err;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+ if (params->audio_encoding !=
+ V4L2_MPEG_AUDIO_ENCODING_AC3)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ } else
+ qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+ return 0;
+
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ /* this setting is read-only for the cx2341x since the
+ V4L2_CID_MPEG_STREAM_TYPE really determines the
+ MPEG-1/2 setting */
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
+ if (err == 0)
+ qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+ return err;
+
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_ASPECT_1x1,
+ V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
+ V4L2_MPEG_VIDEO_ASPECT_4x3);
+
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
+
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
+ params->is_50hz ? 12 : 15);
+
+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
+
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
+ if (err == 0 &&
+ params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return err;
+
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
+
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
+ if (err == 0 &&
+ params->video_bitrate_mode ==
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return err;
+
+ case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
+ return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
+
+ case V4L2_CID_MPEG_VIDEO_MUTE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
+
+ case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */
+ return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
+
+ /* CX23415/6 specific */
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+ return cx2341x_ctrl_query_fill(qctrl,
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
+ default_params.video_spatial_filter_mode);
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+ cx2341x_ctrl_query_fill(qctrl, 0, 15, 1,
+ default_params.video_spatial_filter);
+ qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+ if (params->video_spatial_filter_mode ==
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+ cx2341x_ctrl_query_fill(qctrl,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
+ 1,
+ default_params.video_luma_spatial_filter_type);
+ if (params->video_spatial_filter_mode ==
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+ cx2341x_ctrl_query_fill(qctrl,
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
+ 1,
+ default_params.video_chroma_spatial_filter_type);
+ if (params->video_spatial_filter_mode ==
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+ return cx2341x_ctrl_query_fill(qctrl,
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
+ default_params.video_temporal_filter_mode);
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+ cx2341x_ctrl_query_fill(qctrl, 0, 31, 1,
+ default_params.video_temporal_filter);
+ qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+ if (params->video_temporal_filter_mode ==
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+ return cx2341x_ctrl_query_fill(qctrl,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
+ default_params.video_median_filter_type);
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+ cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
+ default_params.video_luma_median_filter_top);
+ qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+ if (params->video_median_filter_type ==
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+ cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
+ default_params.video_luma_median_filter_bottom);
+ qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+ if (params->video_median_filter_type ==
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+ cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
+ default_params.video_chroma_median_filter_top);
+ qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+ if (params->video_median_filter_type ==
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+ cx2341x_ctrl_query_fill(qctrl, 0, 255, 1,
+ default_params.video_chroma_median_filter_bottom);
+ qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
+ if (params->video_median_filter_type ==
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
+
+ case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
+ return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1,
+ default_params.stream_insert_nav_packets);
+
+ default:
+ return -EINVAL;
+
+ }
+}
+EXPORT_SYMBOL(cx2341x_ctrl_query);
+
+const char * const *cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
+{
+ static const char * const mpeg_stream_type_without_ts[] = {
+ "MPEG-2 Program Stream",
+ "",
+ "MPEG-1 System Stream",
+ "MPEG-2 DVD-compatible Stream",
+ "MPEG-1 VCD-compatible Stream",
+ "MPEG-2 SVCD-compatible Stream",
+ NULL
+ };
+
+ static const char *mpeg_stream_type_with_ts[] = {
+ "MPEG-2 Program Stream",
+ "MPEG-2 Transport Stream",
+ "MPEG-1 System Stream",
+ "MPEG-2 DVD-compatible Stream",
+ "MPEG-1 VCD-compatible Stream",
+ "MPEG-2 SVCD-compatible Stream",
+ NULL
+ };
+
+ static const char *mpeg_audio_encoding_l2_ac3[] = {
+ "",
+ "MPEG-1/2 Layer II",
+ "",
+ "",
+ "AC-3",
+ NULL
+ };
+
+ switch (id) {
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ return (p->capabilities & CX2341X_CAP_HAS_TS) ?
+ mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
+ mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
+ case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
+ case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
+ return NULL;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+ case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+ return cx2341x_get_menu(id);
+ default:
+ return v4l2_ctrl_get_menu(id);
+ }
+}
+EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
+
+static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
+{
+ params->audio_properties =
+ (params->audio_sampling_freq << 0) |
+ (params->audio_mode << 8) |
+ (params->audio_mode_extension << 10) |
+ (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
+ ? 3 : params->audio_emphasis) << 12) |
+ (params->audio_crc << 14);
+
+ if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
+ params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
+ params->audio_properties |=
+ /* Not sure if this MPEG Layer II setting is required */
+ ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
+ (params->audio_ac3_bitrate << 4) |
+ (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
+ } else {
+ /* Assuming MPEG Layer II */
+ params->audio_properties |=
+ ((3 - params->audio_encoding) << 2) |
+ ((1 + params->audio_l2_bitrate) << 4);
+ }
+}
+
+int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
+ struct v4l2_ext_controls *ctrls, unsigned int cmd)
+{
+ int err = 0;
+ int i;
+
+ if (cmd == VIDIOC_G_EXT_CTRLS) {
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+ err = cx2341x_get_ctrl(params, ctrl);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+ return err;
+ }
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ctrl = ctrls->controls + i;
+ struct v4l2_queryctrl qctrl;
+ const char * const *menu_items = NULL;
+
+ qctrl.id = ctrl->id;
+ err = cx2341x_ctrl_query(params, &qctrl);
+ if (err)
+ break;
+ if (qctrl.type == V4L2_CTRL_TYPE_MENU)
+ menu_items = cx2341x_ctrl_get_menu(params, qctrl.id);
+ err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
+ if (err)
+ break;
+ err = cx2341x_set_ctrl(params, busy, ctrl);
+ if (err)
+ break;
+ }
+ if (err == 0 &&
+ params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
+ params->video_bitrate_peak < params->video_bitrate) {
+ err = -ERANGE;
+ ctrls->error_idx = ctrls->count;
+ }
+ if (err)
+ ctrls->error_idx = i;
+ else
+ cx2341x_calc_audio_properties(params);
+ return err;
+}
+EXPORT_SYMBOL(cx2341x_ext_ctrls);
+
+void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
+{
+ *p = default_params;
+ cx2341x_calc_audio_properties(p);
+}
+EXPORT_SYMBOL(cx2341x_fill_defaults);
+
+static int cx2341x_api(void *priv, cx2341x_mbox_func func,
+ u32 cmd, int args, ...)
+{
+ u32 data[CX2341X_MBOX_MAX_DATA];
+ va_list vargs;
+ int i;
+
+ va_start(vargs, args);
+
+ for (i = 0; i < args; i++)
+ data[i] = va_arg(vargs, int);
+ va_end(vargs);
+ return func(priv, cmd, args, 0, data);
+}
+
+#define NEQ(field) (old->field != new->field)
+
+int cx2341x_update(void *priv, cx2341x_mbox_func func,
+ const struct cx2341x_mpeg_params *old,
+ const struct cx2341x_mpeg_params *new)
+{
+ static int mpeg_stream_type[] = {
+ 0, /* MPEG-2 PS */
+ 1, /* MPEG-2 TS */
+ 2, /* MPEG-1 SS */
+ 14, /* DVD */
+ 11, /* VCD */
+ 12, /* SVCD */
+ };
+
+ int err = 0;
+ int force = (old == NULL);
+ u16 temporal = new->video_temporal_filter;
+
+ cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
+
+ if (force || NEQ(is_50hz)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1,
+ new->is_50hz);
+ if (err) return err;
+ }
+
+ if (force || NEQ(width) || NEQ(height) || NEQ(video_encoding)) {
+ u16 w = new->width;
+ u16 h = new->height;
+
+ if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
+ w /= 2;
+ h /= 2;
+ }
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2,
+ h, w);
+ if (err) return err;
+ }
+ if (force || NEQ(stream_type)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1,
+ mpeg_stream_type[new->stream_type]);
+ if (err) return err;
+ }
+ if (force || NEQ(video_aspect)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1,
+ 1 + new->video_aspect);
+ if (err) return err;
+ }
+ if (force || NEQ(video_b_frames) || NEQ(video_gop_size)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
+ new->video_gop_size, new->video_b_frames + 1);
+ if (err) return err;
+ }
+ if (force || NEQ(video_gop_closure)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1,
+ new->video_gop_closure);
+ if (err) return err;
+ }
+ if (force || NEQ(audio_properties)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES,
+ 1, new->audio_properties);
+ if (err) return err;
+ }
+ if (force || NEQ(audio_mute)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1,
+ new->audio_mute);
+ if (err) return err;
+ }
+ if (force || NEQ(video_bitrate_mode) || NEQ(video_bitrate) ||
+ NEQ(video_bitrate_peak)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
+ new->video_bitrate_mode, new->video_bitrate,
+ new->video_bitrate_peak / 400, 0, 0);
+ if (err) return err;
+ }
+ if (force || NEQ(video_spatial_filter_mode) ||
+ NEQ(video_temporal_filter_mode) ||
+ NEQ(video_median_filter_type)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE,
+ 2, new->video_spatial_filter_mode |
+ (new->video_temporal_filter_mode << 1),
+ new->video_median_filter_type);
+ if (err) return err;
+ }
+ if (force || NEQ(video_luma_median_filter_bottom) ||
+ NEQ(video_luma_median_filter_top) ||
+ NEQ(video_chroma_median_filter_bottom) ||
+ NEQ(video_chroma_median_filter_top)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
+ new->video_luma_median_filter_bottom,
+ new->video_luma_median_filter_top,
+ new->video_chroma_median_filter_bottom,
+ new->video_chroma_median_filter_top);
+ if (err) return err;
+ }
+ if (force || NEQ(video_luma_spatial_filter_type) ||
+ NEQ(video_chroma_spatial_filter_type)) {
+ err = cx2341x_api(priv, func,
+ CX2341X_ENC_SET_SPATIAL_FILTER_TYPE,
+ 2, new->video_luma_spatial_filter_type,
+ new->video_chroma_spatial_filter_type);
+ if (err) return err;
+ }
+ if (force || NEQ(video_spatial_filter) ||
+ old->video_temporal_filter != temporal) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS,
+ 2, new->video_spatial_filter, temporal);
+ if (err) return err;
+ }
+ if (force || NEQ(video_temporal_decimation)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE,
+ 1, new->video_temporal_decimation);
+ if (err) return err;
+ }
+ if (force || NEQ(video_mute) ||
+ (new->video_mute && NEQ(video_mute_yuv))) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1,
+ new->video_mute | (new->video_mute_yuv << 8));
+ if (err) return err;
+ }
+ if (force || NEQ(stream_insert_nav_packets)) {
+ err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2,
+ 7, new->stream_insert_nav_packets);
+ if (err) return err;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(cx2341x_update);
+
+static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id)
+{
+ const char * const *menu = cx2341x_ctrl_get_menu(p, id);
+ struct v4l2_ext_control ctrl;
+
+ if (menu == NULL)
+ goto invalid;
+ ctrl.id = id;
+ if (cx2341x_get_ctrl(p, &ctrl))
+ goto invalid;
+ while (ctrl.value-- && *menu) menu++;
+ if (*menu == NULL)
+ goto invalid;
+ return *menu;
+
+invalid:
+ return "<invalid>";
+}
+
+void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
+{
+ int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
+
+ /* Stream */
+ printk(KERN_INFO "%s: Stream: %s",
+ prefix,
+ cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
+ if (p->stream_insert_nav_packets)
+ printk(" (with navigation packets)");
+ printk("\n");
+ printk(KERN_INFO "%s: VBI Format: %s\n",
+ prefix,
+ cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
+
+ /* Video */
+ printk(KERN_INFO "%s: Video: %dx%d, %d fps%s\n",
+ prefix,
+ p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
+ p->is_50hz ? 25 : 30,
+ (p->video_mute) ? " (muted)" : "");
+ printk(KERN_INFO "%s: Video: %s, %s, %s, %d",
+ prefix,
+ cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
+ cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
+ cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
+ p->video_bitrate);
+ if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
+ printk(", Peak %d", p->video_bitrate_peak);
+ printk("\n");
+ printk(KERN_INFO
+ "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure\n",
+ prefix,
+ p->video_gop_size, p->video_b_frames,
+ p->video_gop_closure ? "" : "No ");
+ if (p->video_temporal_decimation)
+ printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
+ prefix, p->video_temporal_decimation);
+
+ /* Audio */
+ printk(KERN_INFO "%s: Audio: %s, %s, %s, %s%s",
+ prefix,
+ cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
+ cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
+ cx2341x_menu_item(p,
+ p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
+ ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
+ : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
+ cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
+ p->audio_mute ? " (muted)" : "");
+ if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
+ printk(", %s", cx2341x_menu_item(p,
+ V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
+ printk(", %s, %s\n",
+ cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
+ cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
+
+ /* Encoding filters */
+ printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n",
+ prefix,
+ cx2341x_menu_item(p,
+ V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
+ cx2341x_menu_item(p,
+ V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
+ cx2341x_menu_item(p,
+ V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
+ p->video_spatial_filter);
+
+ printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
+ prefix,
+ cx2341x_menu_item(p,
+ V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
+ p->video_temporal_filter);
+ printk(KERN_INFO
+ "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n",
+ prefix,
+ cx2341x_menu_item(p,
+ V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
+ p->video_luma_median_filter_bottom,
+ p->video_luma_median_filter_top,
+ p->video_chroma_median_filter_bottom,
+ p->video_chroma_median_filter_top);
+}
+EXPORT_SYMBOL(cx2341x_log_status);
+
+
+
+/********************** NEW CODE *********************/
+
+static inline struct cx2341x_handler *to_cxhdl(struct v4l2_ctrl *ctrl)
+{
+ return container_of(ctrl->handler, struct cx2341x_handler, hdl);
+}
+
+static int cx2341x_hdl_api(struct cx2341x_handler *hdl,
+ u32 cmd, int args, ...)
+{
+ u32 data[CX2341X_MBOX_MAX_DATA];
+ va_list vargs;
+ int i;
+
+ va_start(vargs, args);
+
+ for (i = 0; i < args; i++)
+ data[i] = va_arg(vargs, int);
+ va_end(vargs);
+ return hdl->func(hdl->priv, cmd, args, 0, data);
+}
+
+/* ctrl->handler->lock is held, so it is safe to access cur.val */
+static inline int cx2341x_neq(struct v4l2_ctrl *ctrl)
+{
+ return ctrl && ctrl->val != ctrl->cur.val;
+}
+
+static int cx2341x_try_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct cx2341x_handler *hdl = to_cxhdl(ctrl);
+ s32 val = ctrl->val;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
+ /* video gop cluster */
+ int b = val + 1;
+ int gop = hdl->video_gop_size->val;
+
+ gop = b * ((gop + b - 1) / b);
+
+ /* Max GOP size = 34 */
+ while (gop > 34)
+ gop -= b;
+ hdl->video_gop_size->val = gop;
+ break;
+ }
+
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ /* stream type cluster */
+ hdl->video_encoding->val =
+ (hdl->stream_type->val == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
+ hdl->stream_type->val == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1 :
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+ if (hdl->video_encoding->val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
+ /* MPEG-1 implies CBR */
+ hdl->video_bitrate_mode->val =
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
+ /* peak bitrate shall be >= normal bitrate */
+ if (hdl->video_bitrate_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
+ hdl->video_bitrate_peak->val < hdl->video_bitrate->val)
+ hdl->video_bitrate_peak->val = hdl->video_bitrate->val;
+ break;
+ }
+ return 0;
+}
+
+static int cx2341x_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ static const int mpeg_stream_type[] = {
+ 0, /* MPEG-2 PS */
+ 1, /* MPEG-2 TS */
+ 2, /* MPEG-1 SS */
+ 14, /* DVD */
+ 11, /* VCD */
+ 12, /* SVCD */
+ };
+ struct cx2341x_handler *hdl = to_cxhdl(ctrl);
+ s32 val = ctrl->val;
+ u32 props;
+ int err;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_STREAM_VBI_FMT:
+ if (hdl->ops && hdl->ops->s_stream_vbi_fmt)
+ return hdl->ops->s_stream_vbi_fmt(hdl, val);
+ return 0;
+
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ return cx2341x_hdl_api(hdl,
+ CX2341X_ENC_SET_ASPECT_RATIO, 1, val + 1);
+
+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+ return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_GOP_CLOSURE, 1, val);
+
+ case V4L2_CID_MPEG_AUDIO_MUTE:
+ return cx2341x_hdl_api(hdl, CX2341X_ENC_MUTE_AUDIO, 1, val);
+
+ case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
+ return cx2341x_hdl_api(hdl,
+ CX2341X_ENC_SET_FRAME_DROP_RATE, 1, val);
+
+ case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
+ return cx2341x_hdl_api(hdl, CX2341X_ENC_MISC, 2, 7, val);
+
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ /* audio properties cluster */
+ props = (hdl->audio_sampling_freq->val << 0) |
+ (hdl->audio_mode->val << 8) |
+ (hdl->audio_mode_extension->val << 10) |
+ (hdl->audio_crc->val << 14);
+ if (hdl->audio_emphasis->val == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
+ props |= 3 << 12;
+ else
+ props |= hdl->audio_emphasis->val << 12;
+
+ if (hdl->audio_encoding->val == V4L2_MPEG_AUDIO_ENCODING_AC3) {
+ props |=
+#if 1
+ /* Not sure if this MPEG Layer II setting is required */
+ ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
+#endif
+ (hdl->audio_ac3_bitrate->val << 4) |
+ (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
+ } else {
+ /* Assuming MPEG Layer II */
+ props |=
+ ((3 - hdl->audio_encoding->val) << 2) |
+ ((1 + hdl->audio_l2_bitrate->val) << 4);
+ }
+ err = cx2341x_hdl_api(hdl,
+ CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, props);
+ if (err)
+ return err;
+
+ hdl->audio_properties = props;
+ if (hdl->audio_ac3_bitrate) {
+ int is_ac3 = hdl->audio_encoding->val ==
+ V4L2_MPEG_AUDIO_ENCODING_AC3;
+
+ v4l2_ctrl_activate(hdl->audio_ac3_bitrate, is_ac3);
+ v4l2_ctrl_activate(hdl->audio_l2_bitrate, !is_ac3);
+ }
+ v4l2_ctrl_activate(hdl->audio_mode_extension,
+ hdl->audio_mode->val == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO);
+ if (cx2341x_neq(hdl->audio_sampling_freq) &&
+ hdl->ops && hdl->ops->s_audio_sampling_freq)
+ return hdl->ops->s_audio_sampling_freq(hdl, hdl->audio_sampling_freq->val);
+ if (cx2341x_neq(hdl->audio_mode) &&
+ hdl->ops && hdl->ops->s_audio_mode)
+ return hdl->ops->s_audio_mode(hdl, hdl->audio_mode->val);
+ return 0;
+
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ /* video gop cluster */
+ return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
+ hdl->video_gop_size->val,
+ hdl->video_b_frames->val + 1);
+
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ /* stream type cluster */
+ err = cx2341x_hdl_api(hdl,
+ CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[val]);
+ if (err)
+ return err;
+
+ err = cx2341x_hdl_api(hdl, CX2341X_ENC_SET_BIT_RATE, 5,
+ hdl->video_bitrate_mode->val,
+ hdl->video_bitrate->val,
+ hdl->video_bitrate_peak->val / 400, 0, 0);
+ if (err)
+ return err;
+
+ v4l2_ctrl_activate(hdl->video_bitrate_mode,
+ hdl->video_encoding->val != V4L2_MPEG_VIDEO_ENCODING_MPEG_1);
+ v4l2_ctrl_activate(hdl->video_bitrate_peak,
+ hdl->video_bitrate_mode->val != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+ if (cx2341x_neq(hdl->video_encoding) &&
+ hdl->ops && hdl->ops->s_video_encoding)
+ return hdl->ops->s_video_encoding(hdl, hdl->video_encoding->val);
+ return 0;
+
+ case V4L2_CID_MPEG_VIDEO_MUTE:
+ /* video mute cluster */
+ return cx2341x_hdl_api(hdl, CX2341X_ENC_MUTE_VIDEO, 1,
+ hdl->video_mute->val |
+ (hdl->video_mute_yuv->val << 8));
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: {
+ int active_filter;
+
+ /* video filter mode */
+ err = cx2341x_hdl_api(hdl, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
+ hdl->video_spatial_filter_mode->val |
+ (hdl->video_temporal_filter_mode->val << 1),
+ hdl->video_median_filter_type->val);
+ if (err)
+ return err;
+
+ active_filter = hdl->video_spatial_filter_mode->val !=
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO;
+ v4l2_ctrl_activate(hdl->video_spatial_filter, active_filter);
+ v4l2_ctrl_activate(hdl->video_luma_spatial_filter_type, active_filter);
+ v4l2_ctrl_activate(hdl->video_chroma_spatial_filter_type, active_filter);
+ active_filter = hdl->video_temporal_filter_mode->val !=
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO;
+ v4l2_ctrl_activate(hdl->video_temporal_filter, active_filter);
+ active_filter = hdl->video_median_filter_type->val !=
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF;
+ v4l2_ctrl_activate(hdl->video_luma_median_filter_bottom, active_filter);
+ v4l2_ctrl_activate(hdl->video_luma_median_filter_top, active_filter);
+ v4l2_ctrl_activate(hdl->video_chroma_median_filter_bottom, active_filter);
+ v4l2_ctrl_activate(hdl->video_chroma_median_filter_top, active_filter);
+ return 0;
+ }
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+ /* video filter type cluster */
+ return cx2341x_hdl_api(hdl,
+ CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
+ hdl->video_luma_spatial_filter_type->val,
+ hdl->video_chroma_spatial_filter_type->val);
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+ /* video filter cluster */
+ return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
+ hdl->video_spatial_filter->val,
+ hdl->video_temporal_filter->val);
+
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+ /* video median cluster */
+ return cx2341x_hdl_api(hdl, CX2341X_ENC_SET_CORING_LEVELS, 4,
+ hdl->video_luma_median_filter_bottom->val,
+ hdl->video_luma_median_filter_top->val,
+ hdl->video_chroma_median_filter_bottom->val,
+ hdl->video_chroma_median_filter_top->val);
+ }
+ return -EINVAL;
+}
+
+static const struct v4l2_ctrl_ops cx2341x_ops = {
+ .try_ctrl = cx2341x_try_ctrl,
+ .s_ctrl = cx2341x_s_ctrl,
+};
+
+static struct v4l2_ctrl *cx2341x_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
+ u32 id, s32 min, s32 max, s32 step, s32 def)
+{
+ struct v4l2_ctrl_config cfg;
+
+ cx2341x_ctrl_fill(id, &cfg.name, &cfg.type, &min, &max, &step, &def, &cfg.flags);
+ cfg.ops = &cx2341x_ops;
+ cfg.id = id;
+ cfg.min = min;
+ cfg.max = max;
+ cfg.def = def;
+ if (cfg.type == V4L2_CTRL_TYPE_MENU) {
+ cfg.step = 0;
+ cfg.menu_skip_mask = step;
+ cfg.qmenu = cx2341x_get_menu(id);
+ } else {
+ cfg.step = step;
+ cfg.menu_skip_mask = 0;
+ }
+ return v4l2_ctrl_new_custom(hdl, &cfg, NULL);
+}
+
+static struct v4l2_ctrl *cx2341x_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
+ u32 id, s32 min, s32 max, s32 step, s32 def)
+{
+ return v4l2_ctrl_new_std(hdl, &cx2341x_ops, id, min, max, step, def);
+}
+
+static struct v4l2_ctrl *cx2341x_ctrl_new_menu(struct v4l2_ctrl_handler *hdl,
+ u32 id, s32 max, s32 mask, s32 def)
+{
+ return v4l2_ctrl_new_std_menu(hdl, &cx2341x_ops, id, max, mask, def);
+}
+
+int cx2341x_handler_init(struct cx2341x_handler *cxhdl,
+ unsigned nr_of_controls_hint)
+{
+ struct v4l2_ctrl_handler *hdl = &cxhdl->hdl;
+ u32 caps = cxhdl->capabilities;
+ int has_sliced_vbi = caps & CX2341X_CAP_HAS_SLICED_VBI;
+ int has_ac3 = caps & CX2341X_CAP_HAS_AC3;
+ int has_ts = caps & CX2341X_CAP_HAS_TS;
+
+ cxhdl->width = 720;
+ cxhdl->height = 480;
+
+ v4l2_ctrl_handler_init(hdl, nr_of_controls_hint);
+
+ /* Add controls in ascending control ID order for fastest
+ insertion time. */
+ cxhdl->stream_type = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_STREAM_TYPE,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, has_ts ? 0 : 2,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
+ cxhdl->stream_vbi_fmt = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_STREAM_VBI_FMT,
+ V4L2_MPEG_STREAM_VBI_FMT_IVTV, has_sliced_vbi ? 0 : 2,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE);
+ cxhdl->audio_sampling_freq = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 0,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
+ cxhdl->audio_encoding = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_AUDIO_ENCODING,
+ V4L2_MPEG_AUDIO_ENCODING_AC3, has_ac3 ? ~0x12 : ~0x2,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
+ cxhdl->audio_l2_bitrate = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_AUDIO_L2_BITRATE,
+ V4L2_MPEG_AUDIO_L2_BITRATE_384K, 0x1ff,
+ V4L2_MPEG_AUDIO_L2_BITRATE_224K);
+ cxhdl->audio_mode = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_AUDIO_MODE,
+ V4L2_MPEG_AUDIO_MODE_MONO, 0,
+ V4L2_MPEG_AUDIO_MODE_STEREO);
+ cxhdl->audio_mode_extension = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 0,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
+ cxhdl->audio_emphasis = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_AUDIO_EMPHASIS,
+ V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 0,
+ V4L2_MPEG_AUDIO_EMPHASIS_NONE);
+ cxhdl->audio_crc = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_AUDIO_CRC,
+ V4L2_MPEG_AUDIO_CRC_CRC16, 0,
+ V4L2_MPEG_AUDIO_CRC_NONE);
+
+ cx2341x_ctrl_new_std(hdl, V4L2_CID_MPEG_AUDIO_MUTE, 0, 1, 1, 0);
+ if (has_ac3)
+ cxhdl->audio_ac3_bitrate = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 0x03,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_224K);
+ cxhdl->video_encoding = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_VIDEO_ENCODING,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 0,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
+ cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_VIDEO_ASPECT,
+ V4L2_MPEG_VIDEO_ASPECT_221x100, 0,
+ V4L2_MPEG_VIDEO_ASPECT_4x3);
+ cxhdl->video_b_frames = cx2341x_ctrl_new_std(hdl,
+ V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 33, 1, 2);
+ cxhdl->video_gop_size = cx2341x_ctrl_new_std(hdl,
+ V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+ 1, 34, 1, cxhdl->is_50hz ? 12 : 15);
+ cx2341x_ctrl_new_std(hdl, V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, 0, 1, 1, 1);
+ cxhdl->video_bitrate_mode = cx2341x_ctrl_new_menu(hdl,
+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 0,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
+ cxhdl->video_bitrate = cx2341x_ctrl_new_std(hdl,
+ V4L2_CID_MPEG_VIDEO_BITRATE,
+ 0, 27000000, 1, 6000000);
+ cxhdl->video_bitrate_peak = cx2341x_ctrl_new_std(hdl,
+ V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+ 0, 27000000, 1, 8000000);
+ cx2341x_ctrl_new_std(hdl,
+ V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, 0, 255, 1, 0);
+ cxhdl->video_mute = cx2341x_ctrl_new_std(hdl,
+ V4L2_CID_MPEG_VIDEO_MUTE, 0, 1, 1, 0);
+ cxhdl->video_mute_yuv = cx2341x_ctrl_new_std(hdl,
+ V4L2_CID_MPEG_VIDEO_MUTE_YUV, 0, 0xffffff, 1, 0x008080);
+
+ /* CX23415/6 specific */
+ cxhdl->video_spatial_filter_mode = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 0,
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
+ cxhdl->video_spatial_filter = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
+ 0, 15, 1, 0);
+ cxhdl->video_luma_spatial_filter_type = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE,
+ 0,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR);
+ cxhdl->video_chroma_spatial_filter_type = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
+ 0,
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR);
+ cxhdl->video_temporal_filter_mode = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO,
+ 0,
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
+ cxhdl->video_temporal_filter = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
+ 0, 31, 1, 8);
+ cxhdl->video_median_filter_type = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG,
+ 0,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
+ cxhdl->video_luma_median_filter_bottom = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
+ 0, 255, 1, 0);
+ cxhdl->video_luma_median_filter_top = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
+ 0, 255, 1, 255);
+ cxhdl->video_chroma_median_filter_bottom = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
+ 0, 255, 1, 0);
+ cxhdl->video_chroma_median_filter_top = cx2341x_ctrl_new_custom(hdl,
+ V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
+ 0, 255, 1, 255);
+ cx2341x_ctrl_new_custom(hdl, V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
+ 0, 1, 1, 0);
+
+ if (hdl->error) {
+ int err = hdl->error;
+
+ v4l2_ctrl_handler_free(hdl);
+ return err;
+ }
+
+ v4l2_ctrl_cluster(8, &cxhdl->audio_sampling_freq);
+ v4l2_ctrl_cluster(2, &cxhdl->video_b_frames);
+ v4l2_ctrl_cluster(5, &cxhdl->stream_type);
+ v4l2_ctrl_cluster(2, &cxhdl->video_mute);
+ v4l2_ctrl_cluster(3, &cxhdl->video_spatial_filter_mode);
+ v4l2_ctrl_cluster(2, &cxhdl->video_luma_spatial_filter_type);
+ v4l2_ctrl_cluster(2, &cxhdl->video_spatial_filter);
+ v4l2_ctrl_cluster(4, &cxhdl->video_luma_median_filter_top);
+
+ return 0;
+}
+EXPORT_SYMBOL(cx2341x_handler_init);
+
+void cx2341x_handler_set_50hz(struct cx2341x_handler *cxhdl, int is_50hz)
+{
+ cxhdl->is_50hz = is_50hz;
+ cxhdl->video_gop_size->default_value = cxhdl->is_50hz ? 12 : 15;
+}
+EXPORT_SYMBOL(cx2341x_handler_set_50hz);
+
+int cx2341x_handler_setup(struct cx2341x_handler *cxhdl)
+{
+ int h = cxhdl->height;
+ int w = cxhdl->width;
+ int err;
+
+ err = cx2341x_hdl_api(cxhdl, CX2341X_ENC_SET_OUTPUT_PORT, 2, cxhdl->port, 0);
+ if (err)
+ return err;
+ err = cx2341x_hdl_api(cxhdl, CX2341X_ENC_SET_FRAME_RATE, 1, cxhdl->is_50hz);
+ if (err)
+ return err;
+
+ if (v4l2_ctrl_g_ctrl(cxhdl->video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
+ w /= 2;
+ h /= 2;
+ }
+ err = cx2341x_hdl_api(cxhdl, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
+ if (err)
+ return err;
+ return v4l2_ctrl_handler_setup(&cxhdl->hdl);
+}
+EXPORT_SYMBOL(cx2341x_handler_setup);
+
+void cx2341x_handler_set_busy(struct cx2341x_handler *cxhdl, int busy)
+{
+ v4l2_ctrl_grab(cxhdl->audio_sampling_freq, busy);
+ v4l2_ctrl_grab(cxhdl->audio_encoding, busy);
+ v4l2_ctrl_grab(cxhdl->audio_l2_bitrate, busy);
+ v4l2_ctrl_grab(cxhdl->audio_ac3_bitrate, busy);
+ v4l2_ctrl_grab(cxhdl->stream_vbi_fmt, busy);
+ v4l2_ctrl_grab(cxhdl->stream_type, busy);
+ v4l2_ctrl_grab(cxhdl->video_bitrate_mode, busy);
+ v4l2_ctrl_grab(cxhdl->video_bitrate, busy);
+ v4l2_ctrl_grab(cxhdl->video_bitrate_peak, busy);
+}
+EXPORT_SYMBOL(cx2341x_handler_set_busy);
diff --git a/drivers/media/common/cypress_firmware.c b/drivers/media/common/cypress_firmware.c
new file mode 100644
index 00000000000..577e82058fd
--- /dev/null
+++ b/drivers/media/common/cypress_firmware.c
@@ -0,0 +1,132 @@
+/* cypress_firmware.c is part of the DVB USB library.
+ *
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for downloading the firmware to Cypress FX 1
+ * and 2 based devices.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include "cypress_firmware.h"
+
+struct usb_cypress_controller {
+ u8 id;
+ const char *name; /* name of the usb controller */
+ u16 cs_reg; /* needs to be restarted,
+ * when the firmware has been downloaded */
+};
+
+static const struct usb_cypress_controller cypress[] = {
+ { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cs_reg = 0x7f92 },
+ { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cs_reg = 0x7f92 },
+ { .id = CYPRESS_FX2, .name = "Cypress FX2", .cs_reg = 0xe600 },
+};
+
+/*
+ * load a firmware packet to the device
+ */
+static int usb_cypress_writemem(struct usb_device *udev, u16 addr, u8 *data,
+ u8 len)
+{
+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
+}
+
+static int cypress_get_hexline(const struct firmware *fw,
+ struct hexline *hx, int *pos)
+{
+ u8 *b = (u8 *) &fw->data[*pos];
+ int data_offs = 4;
+
+ if (*pos >= fw->size)
+ return 0;
+
+ memset(hx, 0, sizeof(struct hexline));
+ hx->len = b[0];
+
+ if ((*pos + hx->len + 4) >= fw->size)
+ return -EINVAL;
+
+ hx->addr = b[1] | (b[2] << 8);
+ hx->type = b[3];
+
+ if (hx->type == 0x04) {
+ /* b[4] and b[5] are the Extended linear address record data
+ * field */
+ hx->addr |= (b[4] << 24) | (b[5] << 16);
+ }
+
+ memcpy(hx->data, &b[data_offs], hx->len);
+ hx->chk = b[hx->len + data_offs];
+ *pos += hx->len + 5;
+
+ return *pos;
+}
+
+int cypress_load_firmware(struct usb_device *udev,
+ const struct firmware *fw, int type)
+{
+ struct hexline *hx;
+ int ret, pos = 0;
+
+ hx = kmalloc(sizeof(struct hexline), GFP_KERNEL);
+ if (!hx) {
+ dev_err(&udev->dev, "%s: kmalloc() failed\n", KBUILD_MODNAME);
+ return -ENOMEM;
+ }
+
+ /* stop the CPU */
+ hx->data[0] = 1;
+ ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
+ if (ret != 1) {
+ dev_err(&udev->dev, "%s: CPU stop failed=%d\n",
+ KBUILD_MODNAME, ret);
+ ret = -EIO;
+ goto err_kfree;
+ }
+
+ /* write firmware to memory */
+ for (;;) {
+ ret = cypress_get_hexline(fw, hx, &pos);
+ if (ret < 0)
+ goto err_kfree;
+ else if (ret == 0)
+ break;
+
+ ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
+ if (ret < 0) {
+ goto err_kfree;
+ } else if (ret != hx->len) {
+ dev_err(&udev->dev,
+ "%s: error while transferring firmware (transferred size=%d, block size=%d)\n",
+ KBUILD_MODNAME, ret, hx->len);
+ ret = -EIO;
+ goto err_kfree;
+ }
+ }
+
+ /* start the CPU */
+ hx->data[0] = 0;
+ ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
+ if (ret != 1) {
+ dev_err(&udev->dev, "%s: CPU start failed=%d\n",
+ KBUILD_MODNAME, ret);
+ ret = -EIO;
+ goto err_kfree;
+ }
+
+ ret = 0;
+err_kfree:
+ kfree(hx);
+ return ret;
+}
+EXPORT_SYMBOL(cypress_load_firmware);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Cypress firmware download");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/cypress_firmware.h b/drivers/media/common/cypress_firmware.h
new file mode 100644
index 00000000000..e493cbc7a52
--- /dev/null
+++ b/drivers/media/common/cypress_firmware.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
+ * see dvb-usb-init.c for copyright information.
+ *
+ * This file contains functions for downloading the firmware to Cypress FX 1
+ * and 2 based devices.
+ *
+ */
+
+#ifndef CYPRESS_FIRMWARE_H
+#define CYPRESS_FIRMWARE_H
+
+#define CYPRESS_AN2135 0
+#define CYPRESS_AN2235 1
+#define CYPRESS_FX2 2
+
+/* commonly used firmware download types and function */
+struct hexline {
+ u8 len;
+ u32 addr;
+ u8 type;
+ u8 data[255];
+ u8 chk;
+};
+
+int cypress_load_firmware(struct usb_device *, const struct firmware *, int);
+
+#endif
diff --git a/drivers/media/common/saa7146/saa7146_core.c b/drivers/media/common/saa7146/saa7146_core.c
index bb6ee5191eb..34b0d0ddeef 100644
--- a/drivers/media/common/saa7146/saa7146_core.c
+++ b/drivers/media/common/saa7146/saa7146_core.c
@@ -411,7 +411,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
saa7146_write(dev, MC2, 0xf8000000);
/* request an interrupt for the saa7146 */
- err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED | IRQF_DISABLED,
+ err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED,
dev->name, dev);
if (err < 0) {
ERR("request_irq() failed\n");
@@ -524,8 +524,6 @@ static void saa7146_remove_one(struct pci_dev *pdev)
DEB_EE("dev:%p\n", dev);
dev->ext->detach(dev);
- /* Zero the PCI drvdata after use. */
- pci_set_drvdata(pdev, NULL);
/* shut down all video dma transfers */
saa7146_write(dev, MC1, 0x00ff0000);
diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c
index b3890bd49df..eda01bc68ab 100644
--- a/drivers/media/common/saa7146/saa7146_fops.c
+++ b/drivers/media/common/saa7146/saa7146_fops.c
@@ -105,7 +105,7 @@ void saa7146_buffer_finish(struct saa7146_dev *dev,
}
q->curr->vb.state = state;
- do_gettimeofday(&q->curr->vb.ts);
+ v4l2_get_timestamp(&q->curr->vb.ts);
wake_up(&q->curr->vb.done);
q->curr = NULL;
@@ -265,8 +265,7 @@ static int fops_release(struct file *file)
DEB_EE("file:%p\n", file);
- if (mutex_lock_interruptible(vdev->lock))
- return -ERESTARTSYS;
+ mutex_lock(vdev->lock);
if (vdev->vfl_type == VFL_TYPE_VBI) {
if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
index 4143d61f79b..30779498c17 100644
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ b/drivers/media/common/saa7146/saa7146_video.c
@@ -1,7 +1,6 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <media/saa7146_vv.h>
-#include <media/v4l2-chip-ident.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>
#include <linux/module.h>
@@ -832,7 +831,7 @@ static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
}
*/
-static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
+static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id)
{
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct saa7146_vv *vv = dev->vv_data;
@@ -856,7 +855,7 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
}
for (i = 0; i < dev->ext_vv_data->num_stds; i++)
- if (*id & dev->ext_vv_data->stds[i].id)
+ if (id & dev->ext_vv_data->stds[i].id)
break;
if (i != dev->ext_vv_data->num_stds) {
vv->standard = &dev->ext_vv_data->stds[i];
@@ -988,26 +987,6 @@ static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type ty
return err;
}
-static int vidioc_g_chip_ident(struct file *file, void *__fh,
- struct v4l2_dbg_chip_ident *chip)
-{
- struct saa7146_fh *fh = __fh;
- struct saa7146_dev *dev = fh->dev;
-
- chip->ident = V4L2_IDENT_NONE;
- chip->revision = 0;
- if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
- if (v4l2_chip_match_host(&chip->match))
- chip->ident = V4L2_IDENT_SAA7146;
- return 0;
- }
- if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
- chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
- return -EINVAL;
- return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
- core, g_chip_ident, chip);
-}
-
const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
@@ -1018,7 +997,6 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
.vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
.vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
.vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
.vidioc_overlay = vidioc_overlay,
.vidioc_g_fbuf = vidioc_g_fbuf,
@@ -1039,7 +1017,6 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
- .vidioc_g_chip_ident = vidioc_g_chip_ident,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
diff --git a/drivers/media/common/siano/Kconfig b/drivers/media/common/siano/Kconfig
index 425aeadfb49..f953d33ee15 100644
--- a/drivers/media/common/siano/Kconfig
+++ b/drivers/media/common/siano/Kconfig
@@ -4,14 +4,30 @@
config SMS_SIANO_MDTV
tristate
- depends on DVB_CORE && RC_CORE && HAS_DMA
+ depends on DVB_CORE && HAS_DMA
+ depends on !RC_CORE || RC_CORE
depends on SMS_USB_DRV || SMS_SDIO_DRV
default y
+
+config SMS_SIANO_RC
+ bool "Enable Remote Controller support for Siano devices"
+ depends on SMS_SIANO_MDTV && RC_CORE
+ depends on SMS_USB_DRV || SMS_SDIO_DRV
+ depends on MEDIA_COMMON_OPTIONS
+ default y
---help---
- Choose Y or M here if you have MDTV receiver with a Siano chipset.
+ Choose Y to select Remote Controller support for Siano driver.
- To compile this driver as a module, choose M here
- (The module will be called smsmdtv).
+config SMS_SIANO_DEBUGFS
+ bool "Enable debugfs for smsdvb"
+ depends on SMS_SIANO_MDTV
+ depends on DEBUG_FS
+ depends on SMS_USB_DRV
+ depends on CONFIG_SMS_USB_DRV = CONFIG_SMS_SDIO_DRV
+
+ ---help---
+ Choose Y to enable visualizing a dump of the frontend
+ statistics response packets via debugfs. Currently, works
+ only with Siano USB devices.
- Further documentation on this driver can be found on the WWW
- at http://www.siano-ms.com/
+ Useful only for developers. In doubt, say N.
diff --git a/drivers/media/common/siano/Makefile b/drivers/media/common/siano/Makefile
index 2a09279e064..4c0567f106b 100644
--- a/drivers/media/common/siano/Makefile
+++ b/drivers/media/common/siano/Makefile
@@ -1,7 +1,16 @@
-smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
+smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o
+smsdvb-objs := smsdvb-main.o
obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
+ifeq ($(CONFIG_SMS_SIANO_RC),y)
+ smsmdtv-objs += smsir.o
+endif
+
+ifeq ($(CONFIG_SMS_SIANO_DEBUGFS),y)
+ smsdvb-objs += smsdvb-debugfs.o
+endif
+
ccflags-y += -Idrivers/media/dvb-core
ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c
index 680c781c8dd..82769993eeb 100644
--- a/drivers/media/common/siano/sms-cards.c
+++ b/drivers/media/common/siano/sms-cards.c
@@ -28,43 +28,53 @@ MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
static struct sms_board sms_boards[] = {
[SMS_BOARD_UNKNOWN] = {
.name = "Unknown board",
+ .type = SMS_UNKNOWN_TYPE,
+ .default_mode = DEVICE_MODE_NONE,
},
[SMS1XXX_BOARD_SIANO_STELLAR] = {
.name = "Siano Stellar Digital Receiver",
.type = SMS_STELLAR,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_SIANO_NOVA_A] = {
.name = "Siano Nova A Digital Receiver",
.type = SMS_NOVA_A0,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_SIANO_NOVA_B] = {
.name = "Siano Nova B Digital Receiver",
.type = SMS_NOVA_B0,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_SIANO_VEGA] = {
.name = "Siano Vega Digital Receiver",
.type = SMS_VEGA,
+ .default_mode = DEVICE_MODE_CMMB,
},
[SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
.name = "Hauppauge Catamount",
.type = SMS_STELLAR,
- .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
+ .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_STELLAR,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
.name = "Hauppauge Okemo-A",
.type = SMS_NOVA_A0,
- .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
+ .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_NOVA_A,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
.name = "Hauppauge Okemo-B",
.type = SMS_NOVA_B0,
- .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
+ .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_NOVA_B,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
.name = "Hauppauge WinTV MiniStick",
.type = SMS_NOVA_B0,
- .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
- .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
+ .fw[DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_HCW_55XXX,
+ .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
.rc_codes = RC_MAP_HAUPPAUGE,
.board_cfg.leds_power = 26,
.board_cfg.led0 = 27,
@@ -77,7 +87,8 @@ static struct sms_board sms_boards[] = {
[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
.name = "Hauppauge WinTV MiniCard",
.type = SMS_NOVA_B0,
- .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
+ .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
.lna_ctrl = 29,
.board_cfg.foreign_lna0_ctrl = 29,
.rf_switch = 17,
@@ -86,18 +97,65 @@ static struct sms_board sms_boards[] = {
[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
.name = "Hauppauge WinTV MiniCard",
.type = SMS_NOVA_B0,
- .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
+ .fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
.lna_ctrl = -1,
},
[SMS1XXX_BOARD_SIANO_NICE] = {
- /* 11 */
.name = "Siano Nice Digital Receiver",
.type = SMS_NOVA_B0,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
},
[SMS1XXX_BOARD_SIANO_VENICE] = {
- /* 12 */
.name = "Siano Venice Digital Receiver",
.type = SMS_VEGA,
+ .default_mode = DEVICE_MODE_CMMB,
+ },
+ [SMS1XXX_BOARD_SIANO_STELLAR_ROM] = {
+ .name = "Siano Stellar Digital Receiver ROM",
+ .type = SMS_STELLAR,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
+ .intf_num = 1,
+ },
+ [SMS1XXX_BOARD_ZTE_DVB_DATA_CARD] = {
+ .name = "ZTE Data Card Digital Receiver",
+ .type = SMS_NOVA_B0,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
+ .intf_num = 5,
+ .mtu = 15792,
+ },
+ [SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD] = {
+ .name = "ONDA Data Card Digital Receiver",
+ .type = SMS_NOVA_B0,
+ .default_mode = DEVICE_MODE_DVBT_BDA,
+ .intf_num = 6,
+ .mtu = 15792,
+ },
+ [SMS1XXX_BOARD_SIANO_MING] = {
+ .name = "Siano Ming Digital Receiver",
+ .type = SMS_MING,
+ .default_mode = DEVICE_MODE_CMMB,
+ },
+ [SMS1XXX_BOARD_SIANO_PELE] = {
+ .name = "Siano Pele Digital Receiver",
+ .type = SMS_PELE,
+ .default_mode = DEVICE_MODE_ISDBT_BDA,
+ },
+ [SMS1XXX_BOARD_SIANO_RIO] = {
+ .name = "Siano Rio Digital Receiver",
+ .type = SMS_RIO,
+ .default_mode = DEVICE_MODE_ISDBT_BDA,
+ },
+ [SMS1XXX_BOARD_SIANO_DENVER_1530] = {
+ .name = "Siano Denver (ATSC-M/H) Digital Receiver",
+ .type = SMS_DENVER_1530,
+ .default_mode = DEVICE_MODE_ATSC,
+ .crystal = 2400,
+ },
+ [SMS1XXX_BOARD_SIANO_DENVER_2160] = {
+ .name = "Siano Denver (TDMB) Digital Receiver",
+ .type = SMS_DENVER_2160,
+ .default_mode = DEVICE_MODE_DAB_TDMB,
},
};
@@ -109,20 +167,21 @@ struct sms_board *sms_get_board(unsigned id)
}
EXPORT_SYMBOL_GPL(sms_get_board);
static inline void sms_gpio_assign_11xx_default_led_config(
- struct smscore_gpio_config *pGpioConfig) {
- pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
- pGpioConfig->InputCharacteristics =
- SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
- pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
- pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
- pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
+ struct smscore_config_gpio *p_gpio_config) {
+ p_gpio_config->direction = SMS_GPIO_DIRECTION_OUTPUT;
+ p_gpio_config->inputcharacteristics =
+ SMS_GPIO_INPUTCHARACTERISTICS_NORMAL;
+ p_gpio_config->outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA;
+ p_gpio_config->outputslewrate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
+ p_gpio_config->pullupdown = SMS_GPIO_PULLUPDOWN_NONE;
}
int sms_board_event(struct smscore_device_t *coredev,
- enum SMS_BOARD_EVENTS gevent) {
- struct smscore_gpio_config MyGpioConfig;
+ enum SMS_BOARD_EVENTS gevent)
+{
+ struct smscore_config_gpio my_gpio_config;
- sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
+ sms_gpio_assign_11xx_default_led_config(&my_gpio_config);
switch (gevent) {
case BOARD_EVENT_POWER_INIT: /* including hotplug */
@@ -182,8 +241,8 @@ static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
.direction = SMS_GPIO_DIRECTION_OUTPUT,
.pullupdown = SMS_GPIO_PULLUPDOWN_NONE,
.inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
- .outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST,
- .outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA,
+ .outputslewrate = SMS_GPIO_OUTPUT_SLEW_RATE_FAST,
+ .outputdriving = SMS_GPIO_OUTPUTDRIVING_S_4mA,
};
if (pin == 0)
@@ -293,19 +352,7 @@ EXPORT_SYMBOL_GPL(sms_board_lna_control);
int sms_board_load_modules(int id)
{
- switch (id) {
- case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
- case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
- case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
- case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
- case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
- case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
- request_module("smsdvb");
- break;
- default:
- /* do nothing */
- break;
- }
+ request_module("smsdvb");
return 0;
}
EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff --git a/drivers/media/common/siano/sms-cards.h b/drivers/media/common/siano/sms-cards.h
index d8cdf756f7c..c63b544c49c 100644
--- a/drivers/media/common/siano/sms-cards.h
+++ b/drivers/media/common/siano/sms-cards.h
@@ -37,6 +37,14 @@
#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
#define SMS1XXX_BOARD_SIANO_NICE 11
#define SMS1XXX_BOARD_SIANO_VENICE 12
+#define SMS1XXX_BOARD_SIANO_STELLAR_ROM 13
+#define SMS1XXX_BOARD_ZTE_DVB_DATA_CARD 14
+#define SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD 15
+#define SMS1XXX_BOARD_SIANO_MING 16
+#define SMS1XXX_BOARD_SIANO_PELE 17
+#define SMS1XXX_BOARD_SIANO_RIO 18
+#define SMS1XXX_BOARD_SIANO_DENVER_1530 19
+#define SMS1XXX_BOARD_SIANO_DENVER_2160 20
struct sms_board_gpio_cfg {
int lna_vhf_exist;
@@ -79,6 +87,12 @@ struct sms_board {
/* gpios */
int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
+
+ char intf_num;
+ int default_mode;
+ unsigned int mtu;
+ unsigned int crystal;
+ struct sms_antenna_config_ST *antenna_config;
};
struct sms_board *sms_get_board(unsigned id);
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
index 9cc55546cc3..050984c5b1e 100644
--- a/drivers/media/common/siano/smscoreapi.c
+++ b/drivers/media/common/siano/smscoreapi.c
@@ -37,7 +37,6 @@
#include "smscoreapi.h"
#include "sms-cards.h"
#include "smsir.h"
-#include "smsendian.h"
static int sms_dbg;
module_param_named(debug, sms_dbg, int, 0644);
@@ -58,11 +57,350 @@ struct smscore_client_t {
struct list_head entry;
struct smscore_device_t *coredev;
void *context;
- struct list_head idlist;
- onresponse_t onresponse_handler;
+ struct list_head idlist;
+ onresponse_t onresponse_handler;
onremove_t onremove_handler;
};
+static char *siano_msgs[] = {
+ [MSG_TYPE_BASE_VAL - MSG_TYPE_BASE_VAL] = "MSG_TYPE_BASE_VAL",
+ [MSG_SMS_GET_VERSION_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_REQ",
+ [MSG_SMS_GET_VERSION_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_RES",
+ [MSG_SMS_MULTI_BRIDGE_CFG - MSG_TYPE_BASE_VAL] = "MSG_SMS_MULTI_BRIDGE_CFG",
+ [MSG_SMS_GPIO_CONFIG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_REQ",
+ [MSG_SMS_GPIO_CONFIG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_RES",
+ [MSG_SMS_GPIO_SET_LEVEL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_SET_LEVEL_REQ",
+ [MSG_SMS_GPIO_SET_LEVEL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_SET_LEVEL_RES",
+ [MSG_SMS_GPIO_GET_LEVEL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_GET_LEVEL_REQ",
+ [MSG_SMS_GPIO_GET_LEVEL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_GET_LEVEL_RES",
+ [MSG_SMS_EEPROM_BURN_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_EEPROM_BURN_IND",
+ [MSG_SMS_LOG_ENABLE_CHANGE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_ENABLE_CHANGE_REQ",
+ [MSG_SMS_LOG_ENABLE_CHANGE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_ENABLE_CHANGE_RES",
+ [MSG_SMS_SET_MAX_TX_MSG_LEN_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_MAX_TX_MSG_LEN_REQ",
+ [MSG_SMS_SET_MAX_TX_MSG_LEN_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_MAX_TX_MSG_LEN_RES",
+ [MSG_SMS_SPI_HALFDUPLEX_TOKEN_HOST_TO_DEVICE - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_HALFDUPLEX_TOKEN_HOST_TO_DEVICE",
+ [MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST",
+ [MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_REQ",
+ [MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_RES",
+ [MSG_SMS_BACKGROUND_SCAN_SIGNAL_DETECTED_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_SIGNAL_DETECTED_IND",
+ [MSG_SMS_BACKGROUND_SCAN_NO_SIGNAL_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_BACKGROUND_SCAN_NO_SIGNAL_IND",
+ [MSG_SMS_CONFIGURE_RF_SWITCH_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIGURE_RF_SWITCH_REQ",
+ [MSG_SMS_CONFIGURE_RF_SWITCH_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIGURE_RF_SWITCH_RES",
+ [MSG_SMS_MRC_PATH_DISCONNECT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_PATH_DISCONNECT_REQ",
+ [MSG_SMS_MRC_PATH_DISCONNECT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_PATH_DISCONNECT_RES",
+ [MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_REQ",
+ [MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_RES",
+ [MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_REQ",
+ [MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_RES",
+ [MSG_WR_REG_RFT_REQ - MSG_TYPE_BASE_VAL] = "MSG_WR_REG_RFT_REQ",
+ [MSG_WR_REG_RFT_RES - MSG_TYPE_BASE_VAL] = "MSG_WR_REG_RFT_RES",
+ [MSG_RD_REG_RFT_REQ - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_RFT_REQ",
+ [MSG_RD_REG_RFT_RES - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_RFT_RES",
+ [MSG_RD_REG_ALL_RFT_REQ - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_ALL_RFT_REQ",
+ [MSG_RD_REG_ALL_RFT_RES - MSG_TYPE_BASE_VAL] = "MSG_RD_REG_ALL_RFT_RES",
+ [MSG_HELP_INT - MSG_TYPE_BASE_VAL] = "MSG_HELP_INT",
+ [MSG_RUN_SCRIPT_INT - MSG_TYPE_BASE_VAL] = "MSG_RUN_SCRIPT_INT",
+ [MSG_SMS_EWS_INBAND_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_EWS_INBAND_REQ",
+ [MSG_SMS_EWS_INBAND_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_EWS_INBAND_RES",
+ [MSG_SMS_RFS_SELECT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RFS_SELECT_REQ",
+ [MSG_SMS_RFS_SELECT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RFS_SELECT_RES",
+ [MSG_SMS_MB_GET_VER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_GET_VER_REQ",
+ [MSG_SMS_MB_GET_VER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_GET_VER_RES",
+ [MSG_SMS_MB_WRITE_CFGFILE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_WRITE_CFGFILE_REQ",
+ [MSG_SMS_MB_WRITE_CFGFILE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_WRITE_CFGFILE_RES",
+ [MSG_SMS_MB_READ_CFGFILE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_READ_CFGFILE_REQ",
+ [MSG_SMS_MB_READ_CFGFILE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_READ_CFGFILE_RES",
+ [MSG_SMS_RD_MEM_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RD_MEM_REQ",
+ [MSG_SMS_RD_MEM_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RD_MEM_RES",
+ [MSG_SMS_WR_MEM_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_WR_MEM_REQ",
+ [MSG_SMS_WR_MEM_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_WR_MEM_RES",
+ [MSG_SMS_UPDATE_MEM_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_UPDATE_MEM_REQ",
+ [MSG_SMS_UPDATE_MEM_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_UPDATE_MEM_RES",
+ [MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_REQ",
+ [MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_RES",
+ [MSG_SMS_RF_TUNE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RF_TUNE_REQ",
+ [MSG_SMS_RF_TUNE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RF_TUNE_RES",
+ [MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_REQ",
+ [MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_RES",
+ [MSG_SMS_ISDBT_SB_RECEPTION_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_SB_RECEPTION_REQ",
+ [MSG_SMS_ISDBT_SB_RECEPTION_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_SB_RECEPTION_RES",
+ [MSG_SMS_GENERIC_EPROM_WRITE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_WRITE_REQ",
+ [MSG_SMS_GENERIC_EPROM_WRITE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_WRITE_RES",
+ [MSG_SMS_GENERIC_EPROM_READ_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_READ_REQ",
+ [MSG_SMS_GENERIC_EPROM_READ_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_EPROM_READ_RES",
+ [MSG_SMS_EEPROM_WRITE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_EEPROM_WRITE_REQ",
+ [MSG_SMS_EEPROM_WRITE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_EEPROM_WRITE_RES",
+ [MSG_SMS_CUSTOM_READ_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_READ_REQ",
+ [MSG_SMS_CUSTOM_READ_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_READ_RES",
+ [MSG_SMS_CUSTOM_WRITE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_WRITE_REQ",
+ [MSG_SMS_CUSTOM_WRITE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CUSTOM_WRITE_RES",
+ [MSG_SMS_INIT_DEVICE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_INIT_DEVICE_REQ",
+ [MSG_SMS_INIT_DEVICE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_INIT_DEVICE_RES",
+ [MSG_SMS_ATSC_SET_ALL_IP_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_SET_ALL_IP_REQ",
+ [MSG_SMS_ATSC_SET_ALL_IP_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_SET_ALL_IP_RES",
+ [MSG_SMS_ATSC_START_ENSEMBLE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_START_ENSEMBLE_REQ",
+ [MSG_SMS_ATSC_START_ENSEMBLE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_START_ENSEMBLE_RES",
+ [MSG_SMS_SET_OUTPUT_MODE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_OUTPUT_MODE_REQ",
+ [MSG_SMS_SET_OUTPUT_MODE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_OUTPUT_MODE_RES",
+ [MSG_SMS_ATSC_IP_FILTER_GET_LIST_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_GET_LIST_REQ",
+ [MSG_SMS_ATSC_IP_FILTER_GET_LIST_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_GET_LIST_RES",
+ [MSG_SMS_SUB_CHANNEL_START_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_START_REQ",
+ [MSG_SMS_SUB_CHANNEL_START_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_START_RES",
+ [MSG_SMS_SUB_CHANNEL_STOP_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_STOP_REQ",
+ [MSG_SMS_SUB_CHANNEL_STOP_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SUB_CHANNEL_STOP_RES",
+ [MSG_SMS_ATSC_IP_FILTER_ADD_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_ADD_REQ",
+ [MSG_SMS_ATSC_IP_FILTER_ADD_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_ADD_RES",
+ [MSG_SMS_ATSC_IP_FILTER_REMOVE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_REQ",
+ [MSG_SMS_ATSC_IP_FILTER_REMOVE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_RES",
+ [MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_REQ",
+ [MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_RES",
+ [MSG_SMS_WAIT_CMD - MSG_TYPE_BASE_VAL] = "MSG_SMS_WAIT_CMD",
+ [MSG_SMS_ADD_PID_FILTER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ADD_PID_FILTER_REQ",
+ [MSG_SMS_ADD_PID_FILTER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ADD_PID_FILTER_RES",
+ [MSG_SMS_REMOVE_PID_FILTER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_REMOVE_PID_FILTER_REQ",
+ [MSG_SMS_REMOVE_PID_FILTER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_REMOVE_PID_FILTER_RES",
+ [MSG_SMS_FAST_INFORMATION_CHANNEL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_FAST_INFORMATION_CHANNEL_REQ",
+ [MSG_SMS_FAST_INFORMATION_CHANNEL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_FAST_INFORMATION_CHANNEL_RES",
+ [MSG_SMS_DAB_CHANNEL - MSG_TYPE_BASE_VAL] = "MSG_SMS_DAB_CHANNEL",
+ [MSG_SMS_GET_PID_FILTER_LIST_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_PID_FILTER_LIST_REQ",
+ [MSG_SMS_GET_PID_FILTER_LIST_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_PID_FILTER_LIST_RES",
+ [MSG_SMS_POWER_DOWN_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_REQ",
+ [MSG_SMS_POWER_DOWN_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_RES",
+ [MSG_SMS_ATSC_SLT_EXIST_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_SLT_EXIST_IND",
+ [MSG_SMS_ATSC_NO_SLT_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_ATSC_NO_SLT_IND",
+ [MSG_SMS_GET_STATISTICS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_REQ",
+ [MSG_SMS_GET_STATISTICS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_RES",
+ [MSG_SMS_SEND_DUMP - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_DUMP",
+ [MSG_SMS_SCAN_START_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_START_REQ",
+ [MSG_SMS_SCAN_START_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_START_RES",
+ [MSG_SMS_SCAN_STOP_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_STOP_REQ",
+ [MSG_SMS_SCAN_STOP_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_STOP_RES",
+ [MSG_SMS_SCAN_PROGRESS_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_PROGRESS_IND",
+ [MSG_SMS_SCAN_COMPLETE_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_SCAN_COMPLETE_IND",
+ [MSG_SMS_LOG_ITEM - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_ITEM",
+ [MSG_SMS_DAB_SUBCHANNEL_RECONFIG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DAB_SUBCHANNEL_RECONFIG_REQ",
+ [MSG_SMS_DAB_SUBCHANNEL_RECONFIG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DAB_SUBCHANNEL_RECONFIG_RES",
+ [MSG_SMS_HO_PER_SLICES_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PER_SLICES_IND",
+ [MSG_SMS_HO_INBAND_POWER_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_INBAND_POWER_IND",
+ [MSG_SMS_MANUAL_DEMOD_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MANUAL_DEMOD_REQ",
+ [MSG_SMS_HO_TUNE_ON_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_ON_REQ",
+ [MSG_SMS_HO_TUNE_ON_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_ON_RES",
+ [MSG_SMS_HO_TUNE_OFF_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_OFF_REQ",
+ [MSG_SMS_HO_TUNE_OFF_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_TUNE_OFF_RES",
+ [MSG_SMS_HO_PEEK_FREQ_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PEEK_FREQ_REQ",
+ [MSG_SMS_HO_PEEK_FREQ_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PEEK_FREQ_RES",
+ [MSG_SMS_HO_PEEK_FREQ_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_HO_PEEK_FREQ_IND",
+ [MSG_SMS_MB_ATTEN_SET_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_ATTEN_SET_REQ",
+ [MSG_SMS_MB_ATTEN_SET_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MB_ATTEN_SET_RES",
+ [MSG_SMS_ENABLE_STAT_IN_I2C_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENABLE_STAT_IN_I2C_REQ",
+ [MSG_SMS_ENABLE_STAT_IN_I2C_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENABLE_STAT_IN_I2C_RES",
+ [MSG_SMS_SET_ANTENNA_CONFIG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_ANTENNA_CONFIG_REQ",
+ [MSG_SMS_SET_ANTENNA_CONFIG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_ANTENNA_CONFIG_RES",
+ [MSG_SMS_GET_STATISTICS_EX_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_EX_REQ",
+ [MSG_SMS_GET_STATISTICS_EX_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_STATISTICS_EX_RES",
+ [MSG_SMS_SLEEP_RESUME_COMP_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_SLEEP_RESUME_COMP_IND",
+ [MSG_SMS_SWITCH_HOST_INTERFACE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWITCH_HOST_INTERFACE_REQ",
+ [MSG_SMS_SWITCH_HOST_INTERFACE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWITCH_HOST_INTERFACE_RES",
+ [MSG_SMS_DATA_DOWNLOAD_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_DOWNLOAD_REQ",
+ [MSG_SMS_DATA_DOWNLOAD_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_DOWNLOAD_RES",
+ [MSG_SMS_DATA_VALIDITY_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_VALIDITY_REQ",
+ [MSG_SMS_DATA_VALIDITY_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_VALIDITY_RES",
+ [MSG_SMS_SWDOWNLOAD_TRIGGER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_TRIGGER_REQ",
+ [MSG_SMS_SWDOWNLOAD_TRIGGER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_TRIGGER_RES",
+ [MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ",
+ [MSG_SMS_SWDOWNLOAD_BACKDOOR_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SWDOWNLOAD_BACKDOOR_RES",
+ [MSG_SMS_GET_VERSION_EX_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_EX_REQ",
+ [MSG_SMS_GET_VERSION_EX_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_VERSION_EX_RES",
+ [MSG_SMS_CLOCK_OUTPUT_CONFIG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CLOCK_OUTPUT_CONFIG_REQ",
+ [MSG_SMS_CLOCK_OUTPUT_CONFIG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CLOCK_OUTPUT_CONFIG_RES",
+ [MSG_SMS_I2C_SET_FREQ_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_I2C_SET_FREQ_REQ",
+ [MSG_SMS_I2C_SET_FREQ_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_I2C_SET_FREQ_RES",
+ [MSG_SMS_GENERIC_I2C_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_I2C_REQ",
+ [MSG_SMS_GENERIC_I2C_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GENERIC_I2C_RES",
+ [MSG_SMS_DVBT_BDA_DATA - MSG_TYPE_BASE_VAL] = "MSG_SMS_DVBT_BDA_DATA",
+ [MSG_SW_RELOAD_REQ - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_REQ",
+ [MSG_SMS_DATA_MSG - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_MSG",
+ [MSG_TABLE_UPLOAD_REQ - MSG_TYPE_BASE_VAL] = "MSG_TABLE_UPLOAD_REQ",
+ [MSG_TABLE_UPLOAD_RES - MSG_TYPE_BASE_VAL] = "MSG_TABLE_UPLOAD_RES",
+ [MSG_SW_RELOAD_START_REQ - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_START_REQ",
+ [MSG_SW_RELOAD_START_RES - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_START_RES",
+ [MSG_SW_RELOAD_EXEC_REQ - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_EXEC_REQ",
+ [MSG_SW_RELOAD_EXEC_RES - MSG_TYPE_BASE_VAL] = "MSG_SW_RELOAD_EXEC_RES",
+ [MSG_SMS_SPI_INT_LINE_SET_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_INT_LINE_SET_REQ",
+ [MSG_SMS_SPI_INT_LINE_SET_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_INT_LINE_SET_RES",
+ [MSG_SMS_GPIO_CONFIG_EX_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_EX_REQ",
+ [MSG_SMS_GPIO_CONFIG_EX_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GPIO_CONFIG_EX_RES",
+ [MSG_SMS_WATCHDOG_ACT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_WATCHDOG_ACT_REQ",
+ [MSG_SMS_WATCHDOG_ACT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_WATCHDOG_ACT_RES",
+ [MSG_SMS_LOOPBACK_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOOPBACK_REQ",
+ [MSG_SMS_LOOPBACK_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOOPBACK_RES",
+ [MSG_SMS_RAW_CAPTURE_START_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_START_REQ",
+ [MSG_SMS_RAW_CAPTURE_START_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_START_RES",
+ [MSG_SMS_RAW_CAPTURE_ABORT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_ABORT_REQ",
+ [MSG_SMS_RAW_CAPTURE_ABORT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_ABORT_RES",
+ [MSG_SMS_RAW_CAPTURE_COMPLETE_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_RAW_CAPTURE_COMPLETE_IND",
+ [MSG_SMS_DATA_PUMP_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_PUMP_IND",
+ [MSG_SMS_DATA_PUMP_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_PUMP_REQ",
+ [MSG_SMS_DATA_PUMP_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DATA_PUMP_RES",
+ [MSG_SMS_FLASH_DL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_FLASH_DL_REQ",
+ [MSG_SMS_EXEC_TEST_1_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXEC_TEST_1_REQ",
+ [MSG_SMS_EXEC_TEST_1_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXEC_TEST_1_RES",
+ [MSG_SMS_ENBALE_TS_INTERFACE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENBALE_TS_INTERFACE_REQ",
+ [MSG_SMS_ENBALE_TS_INTERFACE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ENBALE_TS_INTERFACE_RES",
+ [MSG_SMS_SPI_SET_BUS_WIDTH_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_SET_BUS_WIDTH_REQ",
+ [MSG_SMS_SPI_SET_BUS_WIDTH_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SPI_SET_BUS_WIDTH_RES",
+ [MSG_SMS_SEND_EMM_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_EMM_REQ",
+ [MSG_SMS_SEND_EMM_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_EMM_RES",
+ [MSG_SMS_DISABLE_TS_INTERFACE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DISABLE_TS_INTERFACE_REQ",
+ [MSG_SMS_DISABLE_TS_INTERFACE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DISABLE_TS_INTERFACE_RES",
+ [MSG_SMS_IS_BUF_FREE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_IS_BUF_FREE_REQ",
+ [MSG_SMS_IS_BUF_FREE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_IS_BUF_FREE_RES",
+ [MSG_SMS_EXT_ANTENNA_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXT_ANTENNA_REQ",
+ [MSG_SMS_EXT_ANTENNA_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXT_ANTENNA_RES",
+ [MSG_SMS_CMMB_GET_NET_OF_FREQ_REQ_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NET_OF_FREQ_REQ_OBSOLETE",
+ [MSG_SMS_CMMB_GET_NET_OF_FREQ_RES_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NET_OF_FREQ_RES_OBSOLETE",
+ [MSG_SMS_BATTERY_LEVEL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_BATTERY_LEVEL_REQ",
+ [MSG_SMS_BATTERY_LEVEL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_BATTERY_LEVEL_RES",
+ [MSG_SMS_CMMB_INJECT_TABLE_REQ_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_INJECT_TABLE_REQ_OBSOLETE",
+ [MSG_SMS_CMMB_INJECT_TABLE_RES_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_INJECT_TABLE_RES_OBSOLETE",
+ [MSG_SMS_FM_RADIO_BLOCK_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_FM_RADIO_BLOCK_IND",
+ [MSG_SMS_HOST_NOTIFICATION_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_HOST_NOTIFICATION_IND",
+ [MSG_SMS_CMMB_GET_CONTROL_TABLE_REQ_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_CONTROL_TABLE_REQ_OBSOLETE",
+ [MSG_SMS_CMMB_GET_CONTROL_TABLE_RES_OBSOLETE - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_CONTROL_TABLE_RES_OBSOLETE",
+ [MSG_SMS_CMMB_GET_NETWORKS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NETWORKS_REQ",
+ [MSG_SMS_CMMB_GET_NETWORKS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_NETWORKS_RES",
+ [MSG_SMS_CMMB_START_SERVICE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_SERVICE_REQ",
+ [MSG_SMS_CMMB_START_SERVICE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_SERVICE_RES",
+ [MSG_SMS_CMMB_STOP_SERVICE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_SERVICE_REQ",
+ [MSG_SMS_CMMB_STOP_SERVICE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_SERVICE_RES",
+ [MSG_SMS_CMMB_ADD_CHANNEL_FILTER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_ADD_CHANNEL_FILTER_REQ",
+ [MSG_SMS_CMMB_ADD_CHANNEL_FILTER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_ADD_CHANNEL_FILTER_RES",
+ [MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_REQ",
+ [MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_RES",
+ [MSG_SMS_CMMB_START_CONTROL_INFO_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_CONTROL_INFO_REQ",
+ [MSG_SMS_CMMB_START_CONTROL_INFO_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_START_CONTROL_INFO_RES",
+ [MSG_SMS_CMMB_STOP_CONTROL_INFO_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_CONTROL_INFO_REQ",
+ [MSG_SMS_CMMB_STOP_CONTROL_INFO_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_STOP_CONTROL_INFO_RES",
+ [MSG_SMS_ISDBT_TUNE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_TUNE_REQ",
+ [MSG_SMS_ISDBT_TUNE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_ISDBT_TUNE_RES",
+ [MSG_SMS_TRANSMISSION_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_TRANSMISSION_IND",
+ [MSG_SMS_PID_STATISTICS_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_PID_STATISTICS_IND",
+ [MSG_SMS_POWER_DOWN_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_IND",
+ [MSG_SMS_POWER_DOWN_CONF - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_DOWN_CONF",
+ [MSG_SMS_POWER_UP_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_UP_IND",
+ [MSG_SMS_POWER_UP_CONF - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_UP_CONF",
+ [MSG_SMS_POWER_MODE_SET_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_MODE_SET_REQ",
+ [MSG_SMS_POWER_MODE_SET_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_POWER_MODE_SET_RES",
+ [MSG_SMS_DEBUG_HOST_EVENT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DEBUG_HOST_EVENT_REQ",
+ [MSG_SMS_DEBUG_HOST_EVENT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DEBUG_HOST_EVENT_RES",
+ [MSG_SMS_NEW_CRYSTAL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_NEW_CRYSTAL_REQ",
+ [MSG_SMS_NEW_CRYSTAL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_NEW_CRYSTAL_RES",
+ [MSG_SMS_CONFIG_SPI_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIG_SPI_REQ",
+ [MSG_SMS_CONFIG_SPI_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CONFIG_SPI_RES",
+ [MSG_SMS_I2C_SHORT_STAT_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_I2C_SHORT_STAT_IND",
+ [MSG_SMS_START_IR_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_START_IR_REQ",
+ [MSG_SMS_START_IR_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_START_IR_RES",
+ [MSG_SMS_IR_SAMPLES_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_IR_SAMPLES_IND",
+ [MSG_SMS_CMMB_CA_SERVICE_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_CA_SERVICE_IND",
+ [MSG_SMS_SLAVE_DEVICE_DETECTED - MSG_TYPE_BASE_VAL] = "MSG_SMS_SLAVE_DEVICE_DETECTED",
+ [MSG_SMS_INTERFACE_LOCK_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_INTERFACE_LOCK_IND",
+ [MSG_SMS_INTERFACE_UNLOCK_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_INTERFACE_UNLOCK_IND",
+ [MSG_SMS_SEND_ROSUM_BUFF_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_ROSUM_BUFF_REQ",
+ [MSG_SMS_SEND_ROSUM_BUFF_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_ROSUM_BUFF_RES",
+ [MSG_SMS_ROSUM_BUFF - MSG_TYPE_BASE_VAL] = "MSG_SMS_ROSUM_BUFF",
+ [MSG_SMS_SET_AES128_KEY_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_AES128_KEY_REQ",
+ [MSG_SMS_SET_AES128_KEY_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_AES128_KEY_RES",
+ [MSG_SMS_MBBMS_WRITE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MBBMS_WRITE_REQ",
+ [MSG_SMS_MBBMS_WRITE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MBBMS_WRITE_RES",
+ [MSG_SMS_MBBMS_READ_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_MBBMS_READ_IND",
+ [MSG_SMS_IQ_STREAM_START_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_START_REQ",
+ [MSG_SMS_IQ_STREAM_START_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_START_RES",
+ [MSG_SMS_IQ_STREAM_STOP_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_STOP_REQ",
+ [MSG_SMS_IQ_STREAM_STOP_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_STOP_RES",
+ [MSG_SMS_IQ_STREAM_DATA_BLOCK - MSG_TYPE_BASE_VAL] = "MSG_SMS_IQ_STREAM_DATA_BLOCK",
+ [MSG_SMS_GET_EEPROM_VERSION_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_EEPROM_VERSION_REQ",
+ [MSG_SMS_GET_EEPROM_VERSION_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_GET_EEPROM_VERSION_RES",
+ [MSG_SMS_SIGNAL_DETECTED_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_SIGNAL_DETECTED_IND",
+ [MSG_SMS_NO_SIGNAL_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_NO_SIGNAL_IND",
+ [MSG_SMS_MRC_SHUTDOWN_SLAVE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_SHUTDOWN_SLAVE_REQ",
+ [MSG_SMS_MRC_SHUTDOWN_SLAVE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_SHUTDOWN_SLAVE_RES",
+ [MSG_SMS_MRC_BRINGUP_SLAVE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_BRINGUP_SLAVE_REQ",
+ [MSG_SMS_MRC_BRINGUP_SLAVE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_BRINGUP_SLAVE_RES",
+ [MSG_SMS_EXTERNAL_LNA_CTRL_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXTERNAL_LNA_CTRL_REQ",
+ [MSG_SMS_EXTERNAL_LNA_CTRL_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_EXTERNAL_LNA_CTRL_RES",
+ [MSG_SMS_SET_PERIODIC_STATISTICS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_PERIODIC_STATISTICS_REQ",
+ [MSG_SMS_SET_PERIODIC_STATISTICS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SET_PERIODIC_STATISTICS_RES",
+ [MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_REQ",
+ [MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_RES",
+ [LOCAL_TUNE - MSG_TYPE_BASE_VAL] = "LOCAL_TUNE",
+ [LOCAL_IFFT_H_ICI - MSG_TYPE_BASE_VAL] = "LOCAL_IFFT_H_ICI",
+ [MSG_RESYNC_REQ - MSG_TYPE_BASE_VAL] = "MSG_RESYNC_REQ",
+ [MSG_SMS_CMMB_GET_MRC_STATISTICS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_MRC_STATISTICS_REQ",
+ [MSG_SMS_CMMB_GET_MRC_STATISTICS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_MRC_STATISTICS_RES",
+ [MSG_SMS_LOG_EX_ITEM - MSG_TYPE_BASE_VAL] = "MSG_SMS_LOG_EX_ITEM",
+ [MSG_SMS_DEVICE_DATA_LOSS_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_DEVICE_DATA_LOSS_IND",
+ [MSG_SMS_MRC_WATCHDOG_TRIGGERED_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_MRC_WATCHDOG_TRIGGERED_IND",
+ [MSG_SMS_USER_MSG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_USER_MSG_REQ",
+ [MSG_SMS_USER_MSG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_USER_MSG_RES",
+ [MSG_SMS_SMART_CARD_INIT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_INIT_REQ",
+ [MSG_SMS_SMART_CARD_INIT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_INIT_RES",
+ [MSG_SMS_SMART_CARD_WRITE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_WRITE_REQ",
+ [MSG_SMS_SMART_CARD_WRITE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_WRITE_RES",
+ [MSG_SMS_SMART_CARD_READ_IND - MSG_TYPE_BASE_VAL] = "MSG_SMS_SMART_CARD_READ_IND",
+ [MSG_SMS_TSE_ENABLE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_TSE_ENABLE_REQ",
+ [MSG_SMS_TSE_ENABLE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_TSE_ENABLE_RES",
+ [MSG_SMS_CMMB_GET_SHORT_STATISTICS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_SHORT_STATISTICS_REQ",
+ [MSG_SMS_CMMB_GET_SHORT_STATISTICS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_GET_SHORT_STATISTICS_RES",
+ [MSG_SMS_LED_CONFIG_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_LED_CONFIG_REQ",
+ [MSG_SMS_LED_CONFIG_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_LED_CONFIG_RES",
+ [MSG_PWM_ANTENNA_REQ - MSG_TYPE_BASE_VAL] = "MSG_PWM_ANTENNA_REQ",
+ [MSG_PWM_ANTENNA_RES - MSG_TYPE_BASE_VAL] = "MSG_PWM_ANTENNA_RES",
+ [MSG_SMS_CMMB_SMD_SN_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SMD_SN_REQ",
+ [MSG_SMS_CMMB_SMD_SN_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SMD_SN_RES",
+ [MSG_SMS_CMMB_SET_CA_CW_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_CW_REQ",
+ [MSG_SMS_CMMB_SET_CA_CW_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_CW_RES",
+ [MSG_SMS_CMMB_SET_CA_SALT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_SALT_REQ",
+ [MSG_SMS_CMMB_SET_CA_SALT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_CMMB_SET_CA_SALT_RES",
+ [MSG_SMS_NSCD_INIT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_INIT_REQ",
+ [MSG_SMS_NSCD_INIT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_INIT_RES",
+ [MSG_SMS_NSCD_PROCESS_SECTION_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_PROCESS_SECTION_REQ",
+ [MSG_SMS_NSCD_PROCESS_SECTION_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_PROCESS_SECTION_RES",
+ [MSG_SMS_DBD_CREATE_OBJECT_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CREATE_OBJECT_REQ",
+ [MSG_SMS_DBD_CREATE_OBJECT_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CREATE_OBJECT_RES",
+ [MSG_SMS_DBD_CONFIGURE_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CONFIGURE_REQ",
+ [MSG_SMS_DBD_CONFIGURE_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_CONFIGURE_RES",
+ [MSG_SMS_DBD_SET_KEYS_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_SET_KEYS_REQ",
+ [MSG_SMS_DBD_SET_KEYS_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_SET_KEYS_RES",
+ [MSG_SMS_DBD_PROCESS_HEADER_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_HEADER_REQ",
+ [MSG_SMS_DBD_PROCESS_HEADER_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_HEADER_RES",
+ [MSG_SMS_DBD_PROCESS_DATA_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_DATA_REQ",
+ [MSG_SMS_DBD_PROCESS_DATA_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_DATA_RES",
+ [MSG_SMS_DBD_PROCESS_GET_DATA_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_GET_DATA_REQ",
+ [MSG_SMS_DBD_PROCESS_GET_DATA_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_DBD_PROCESS_GET_DATA_RES",
+ [MSG_SMS_NSCD_OPEN_SESSION_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_OPEN_SESSION_REQ",
+ [MSG_SMS_NSCD_OPEN_SESSION_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_NSCD_OPEN_SESSION_RES",
+ [MSG_SMS_SEND_HOST_DATA_TO_DEMUX_REQ - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_HOST_DATA_TO_DEMUX_REQ",
+ [MSG_SMS_SEND_HOST_DATA_TO_DEMUX_RES - MSG_TYPE_BASE_VAL] = "MSG_SMS_SEND_HOST_DATA_TO_DEMUX_RES",
+ [MSG_LAST_MSG_TYPE - MSG_TYPE_BASE_VAL] = "MSG_LAST_MSG_TYPE",
+};
+
+char *smscore_translate_msg(enum msg_types msgtype)
+{
+ int i = msgtype - MSG_TYPE_BASE_VAL;
+ char *msg;
+
+ if (i < 0 || i >= ARRAY_SIZE(siano_msgs))
+ return "Unknown msg type";
+
+ msg = siano_msgs[i];
+
+ if (!*msg)
+ return "Unknown msg type";
+
+ return msg;
+}
+EXPORT_SYMBOL_GPL(smscore_translate_msg);
+
void smscore_set_board_id(struct smscore_device_t *core, int id)
{
core->board_id = id;
@@ -96,7 +434,7 @@ static struct mutex g_smscore_deviceslock;
static struct list_head g_smscore_registry;
static struct mutex g_smscore_registrylock;
-static int default_mode = 4;
+static int default_mode = DEVICE_MODE_NONE;
module_param(default_mode, int, 0644);
MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
@@ -151,10 +489,10 @@ static enum sms_device_type_st smscore_registry_gettype(char *devpath)
else
sms_err("No registry found.");
- return -1;
+ return -EINVAL;
}
-void smscore_registry_setmode(char *devpath, int mode)
+static void smscore_registry_setmode(char *devpath, int mode)
{
struct smscore_registry_entry_t *entry;
@@ -294,10 +632,11 @@ static struct
smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
dma_addr_t common_buffer_phys)
{
- struct smscore_buffer_t *cb =
- kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
+ struct smscore_buffer_t *cb;
+
+ cb = kzalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
if (!cb) {
- sms_info("kmalloc(...) failed");
+ sms_info("kzalloc(...) failed");
return NULL;
}
@@ -344,6 +683,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
/* init completion events */
init_completion(&dev->version_ex_done);
init_completion(&dev->data_download_done);
+ init_completion(&dev->data_validity_done);
init_completion(&dev->trigger_done);
init_completion(&dev->init_device_done);
init_completion(&dev->reload_start_done);
@@ -370,9 +710,10 @@ int smscore_register_device(struct smsdevice_params_t *params,
for (buffer = dev->common_buffer;
dev->num_buffers < params->num_buffers;
dev->num_buffers++, buffer += params->buffer_size) {
- struct smscore_buffer_t *cb =
- smscore_createbuffer(buffer, dev->common_buffer,
- dev->common_buffer_phys);
+ struct smscore_buffer_t *cb;
+
+ cb = smscore_createbuffer(buffer, dev->common_buffer,
+ dev->common_buffer_phys);
if (!cb) {
smscore_unregister_device(dev);
return -ENOMEM;
@@ -384,6 +725,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
sms_info("allocated %d buffers", dev->num_buffers);
dev->mode = DEVICE_MODE_NONE;
+ dev->board_id = SMS_BOARD_UNKNOWN;
dev->context = params->context;
dev->device = params->device;
dev->setmode_handler = params->setmode_handler;
@@ -413,7 +755,13 @@ EXPORT_SYMBOL_GPL(smscore_register_device);
static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
void *buffer, size_t size, struct completion *completion) {
- int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
+ int rc;
+
+ if (completion == NULL)
+ return -EINVAL;
+ init_completion(completion);
+
+ rc = coredev->sendrequest_handler(coredev->context, buffer, size);
if (rc < 0) {
sms_info("sendrequest returned error %d", rc);
return rc;
@@ -444,24 +792,22 @@ static int smscore_init_ir(struct smscore_device_t *coredev)
if (rc != 0)
sms_err("Error initialization DTV IR sub-module");
else {
- buffer = kmalloc(sizeof(struct SmsMsgData_ST2) +
+ buffer = kmalloc(sizeof(struct sms_msg_data2) +
SMS_DMA_ALIGNMENT,
GFP_KERNEL | GFP_DMA);
if (buffer) {
- struct SmsMsgData_ST2 *msg =
- (struct SmsMsgData_ST2 *)
+ struct sms_msg_data2 *msg =
+ (struct sms_msg_data2 *)
SMS_ALIGN_ADDRESS(buffer);
- SMS_INIT_MSG(&msg->xMsgHeader,
+ SMS_INIT_MSG(&msg->x_msg_header,
MSG_SMS_START_IR_REQ,
- sizeof(struct SmsMsgData_ST2));
- msg->msgData[0] = coredev->ir.controller;
- msg->msgData[1] = coredev->ir.timeout;
+ sizeof(struct sms_msg_data2));
+ msg->msg_data[0] = coredev->ir.controller;
+ msg->msg_data[1] = coredev->ir.timeout;
- smsendian_handle_tx_message(
- (struct SmsMsgHdr_ST2 *)msg);
rc = smscore_sendrequest_and_wait(coredev, msg,
- msg->xMsgHeader. msgLength,
+ msg->x_msg_header. msg_length,
&coredev->ir_init_done);
kfree(buffer);
@@ -476,21 +822,82 @@ static int smscore_init_ir(struct smscore_device_t *coredev)
}
/**
+ * configures device features according to board configuration structure.
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ *
+ * @return 0 on success, <0 on error.
+ */
+static int smscore_configure_board(struct smscore_device_t *coredev)
+{
+ struct sms_board *board;
+
+ board = sms_get_board(coredev->board_id);
+ if (!board) {
+ sms_err("no board configuration exist.");
+ return -EINVAL;
+ }
+
+ if (board->mtu) {
+ struct sms_msg_data mtu_msg;
+ sms_debug("set max transmit unit %d", board->mtu);
+
+ mtu_msg.x_msg_header.msg_src_id = 0;
+ mtu_msg.x_msg_header.msg_dst_id = HIF_TASK;
+ mtu_msg.x_msg_header.msg_flags = 0;
+ mtu_msg.x_msg_header.msg_type = MSG_SMS_SET_MAX_TX_MSG_LEN_REQ;
+ mtu_msg.x_msg_header.msg_length = sizeof(mtu_msg);
+ mtu_msg.msg_data[0] = board->mtu;
+
+ coredev->sendrequest_handler(coredev->context, &mtu_msg,
+ sizeof(mtu_msg));
+ }
+
+ if (board->crystal) {
+ struct sms_msg_data crys_msg;
+ sms_debug("set crystal value %d", board->crystal);
+
+ SMS_INIT_MSG(&crys_msg.x_msg_header,
+ MSG_SMS_NEW_CRYSTAL_REQ,
+ sizeof(crys_msg));
+ crys_msg.msg_data[0] = board->crystal;
+
+ coredev->sendrequest_handler(coredev->context, &crys_msg,
+ sizeof(crys_msg));
+ }
+
+ return 0;
+}
+
+/**
* sets initial device mode and notifies client hotplugs that device is ready
*
* @param coredev pointer to a coredev object returned by
- * smscore_register_device
+ * smscore_register_device
*
* @return 0 on success, <0 on error.
*/
int smscore_start_device(struct smscore_device_t *coredev)
{
- int rc = smscore_set_device_mode(
- coredev, smscore_registry_getmode(coredev->devpath));
+ int rc;
+ int board_id = smscore_get_board_id(coredev);
+ int mode = smscore_registry_getmode(coredev->devpath);
+
+ /* Device is initialized as DEVICE_MODE_NONE */
+ if (board_id != SMS_BOARD_UNKNOWN && mode == DEVICE_MODE_NONE)
+ mode = sms_get_board(board_id)->default_mode;
+
+ rc = smscore_set_device_mode(coredev, mode);
if (rc < 0) {
sms_info("set device mode faile , rc %d", rc);
return rc;
}
+ rc = smscore_configure_board(coredev);
+ if (rc < 0) {
+ sms_info("configure board failed , rc %d", rc);
+ return rc;
+ }
kmutex_lock(&g_smscore_deviceslock);
@@ -509,18 +916,19 @@ EXPORT_SYMBOL_GPL(smscore_start_device);
static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
void *buffer, size_t size)
{
- struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
- struct SmsMsgHdr_ST *msg;
- u32 mem_address;
- u8 *payload = firmware->Payload;
+ struct sms_firmware *firmware = (struct sms_firmware *) buffer;
+ struct sms_msg_data4 *msg;
+ u32 mem_address, calc_checksum = 0;
+ u32 i, *ptr;
+ u8 *payload = firmware->payload;
int rc = 0;
- firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
- firmware->Length = le32_to_cpu(firmware->Length);
+ firmware->start_address = le32_to_cpup((__le32 *)&firmware->start_address);
+ firmware->length = le32_to_cpup((__le32 *)&firmware->length);
- mem_address = firmware->StartAddress;
+ mem_address = firmware->start_address;
sms_info("loading FW to addr 0x%x size %d",
- mem_address, firmware->Length);
+ mem_address, firmware->length);
if (coredev->preload_handler) {
rc = coredev->preload_handler(coredev->context);
if (rc < 0)
@@ -534,35 +942,36 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
if (coredev->mode != DEVICE_MODE_NONE) {
sms_debug("sending reload command.");
- SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
- sizeof(struct SmsMsgHdr_ST));
+ SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_START_REQ,
+ sizeof(struct sms_msg_hdr));
rc = smscore_sendrequest_and_wait(coredev, msg,
- msg->msgLength,
+ msg->x_msg_header.msg_length,
&coredev->reload_start_done);
+ if (rc < 0) {
+ sms_err("device reload failed, rc %d", rc);
+ goto exit_fw_download;
+ }
mem_address = *(u32 *) &payload[20];
}
+ for (i = 0, ptr = (u32 *)firmware->payload; i < firmware->length/4 ;
+ i++, ptr++)
+ calc_checksum += *ptr;
+
while (size && rc >= 0) {
- struct SmsDataDownload_ST *DataMsg =
- (struct SmsDataDownload_ST *) msg;
- int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
+ struct sms_data_download *data_msg =
+ (struct sms_data_download *) msg;
+ int payload_size = min_t(int, size, SMS_MAX_PAYLOAD_SIZE);
- SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
- (u16)(sizeof(struct SmsMsgHdr_ST) +
+ SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_DOWNLOAD_REQ,
+ (u16)(sizeof(struct sms_msg_hdr) +
sizeof(u32) + payload_size));
- DataMsg->MemAddr = mem_address;
- memcpy(DataMsg->Payload, payload, payload_size);
+ data_msg->mem_addr = mem_address;
+ memcpy(data_msg->payload, payload, payload_size);
- if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
- (coredev->mode == DEVICE_MODE_NONE))
- rc = coredev->sendrequest_handler(
- coredev->context, DataMsg,
- DataMsg->xMsgHeader.msgLength);
- else
- rc = smscore_sendrequest_and_wait(
- coredev, DataMsg,
- DataMsg->xMsgHeader.msgLength,
+ rc = smscore_sendrequest_and_wait(coredev, data_msg,
+ data_msg->x_msg_header.msg_length,
&coredev->data_download_done);
payload += payload_size;
@@ -570,50 +979,158 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
mem_address += payload_size;
}
- if (rc >= 0) {
- if (coredev->mode == DEVICE_MODE_NONE) {
- struct SmsMsgData_ST *TriggerMsg =
- (struct SmsMsgData_ST *) msg;
-
- SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
- sizeof(struct SmsMsgHdr_ST) +
- sizeof(u32) * 5);
-
- TriggerMsg->msgData[0] = firmware->StartAddress;
- /* Entry point */
- TriggerMsg->msgData[1] = 5; /* Priority */
- TriggerMsg->msgData[2] = 0x200; /* Stack size */
- TriggerMsg->msgData[3] = 0; /* Parameter */
- TriggerMsg->msgData[4] = 4; /* Task ID */
-
- if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
- rc = coredev->sendrequest_handler(
- coredev->context, TriggerMsg,
- TriggerMsg->xMsgHeader.msgLength);
- msleep(100);
- } else
- rc = smscore_sendrequest_and_wait(
- coredev, TriggerMsg,
- TriggerMsg->xMsgHeader.msgLength,
+ if (rc < 0)
+ goto exit_fw_download;
+
+ sms_debug("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x",
+ calc_checksum);
+ SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_DATA_VALIDITY_REQ,
+ sizeof(msg->x_msg_header) +
+ sizeof(u32) * 3);
+ msg->msg_data[0] = firmware->start_address;
+ /* Entry point */
+ msg->msg_data[1] = firmware->length;
+ msg->msg_data[2] = 0; /* Regular checksum*/
+ rc = smscore_sendrequest_and_wait(coredev, msg,
+ msg->x_msg_header.msg_length,
+ &coredev->data_validity_done);
+ if (rc < 0)
+ goto exit_fw_download;
+
+ if (coredev->mode == DEVICE_MODE_NONE) {
+ struct sms_msg_data *trigger_msg =
+ (struct sms_msg_data *) msg;
+
+ sms_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ");
+ SMS_INIT_MSG(&msg->x_msg_header,
+ MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
+ sizeof(struct sms_msg_hdr) +
+ sizeof(u32) * 5);
+
+ trigger_msg->msg_data[0] = firmware->start_address;
+ /* Entry point */
+ trigger_msg->msg_data[1] = 6; /* Priority */
+ trigger_msg->msg_data[2] = 0x200; /* Stack size */
+ trigger_msg->msg_data[3] = 0; /* Parameter */
+ trigger_msg->msg_data[4] = 4; /* Task ID */
+
+ rc = smscore_sendrequest_and_wait(coredev, trigger_msg,
+ trigger_msg->x_msg_header.msg_length,
&coredev->trigger_done);
- } else {
- SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
- sizeof(struct SmsMsgHdr_ST));
-
- rc = coredev->sendrequest_handler(coredev->context,
- msg, msg->msgLength);
- }
- msleep(500);
+ } else {
+ SMS_INIT_MSG(&msg->x_msg_header, MSG_SW_RELOAD_EXEC_REQ,
+ sizeof(struct sms_msg_hdr));
+ rc = coredev->sendrequest_handler(coredev->context, msg,
+ msg->x_msg_header.msg_length);
}
- sms_debug("rc=%d, postload=%p ", rc,
- coredev->postload_handler);
+ if (rc < 0)
+ goto exit_fw_download;
+ /*
+ * backward compatibility - wait to device_ready_done for
+ * not more than 400 ms
+ */
+ msleep(400);
+
+exit_fw_download:
kfree(msg);
- return ((rc >= 0) && coredev->postload_handler) ?
- coredev->postload_handler(coredev->context) :
- rc;
+ if (coredev->postload_handler) {
+ sms_debug("rc=%d, postload=0x%p", rc, coredev->postload_handler);
+ if (rc >= 0)
+ return coredev->postload_handler(coredev->context);
+ }
+
+ sms_debug("rc=%d", rc);
+ return rc;
+}
+
+static char *smscore_fw_lkup[][DEVICE_MODE_MAX] = {
+ [SMS_NOVA_A0] = {
+ [DEVICE_MODE_DVBT] = SMS_FW_DVB_NOVA_12MHZ,
+ [DEVICE_MODE_DVBH] = SMS_FW_DVB_NOVA_12MHZ,
+ [DEVICE_MODE_DAB_TDMB] = SMS_FW_TDMB_NOVA_12MHZ,
+ [DEVICE_MODE_DVBT_BDA] = SMS_FW_DVB_NOVA_12MHZ,
+ [DEVICE_MODE_ISDBT] = SMS_FW_ISDBT_NOVA_12MHZ,
+ [DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_NOVA_12MHZ,
+ },
+ [SMS_NOVA_B0] = {
+ [DEVICE_MODE_DVBT] = SMS_FW_DVB_NOVA_12MHZ_B0,
+ [DEVICE_MODE_DVBH] = SMS_FW_DVB_NOVA_12MHZ_B0,
+ [DEVICE_MODE_DAB_TDMB] = SMS_FW_TDMB_NOVA_12MHZ_B0,
+ [DEVICE_MODE_DVBT_BDA] = SMS_FW_DVB_NOVA_12MHZ_B0,
+ [DEVICE_MODE_ISDBT] = SMS_FW_ISDBT_NOVA_12MHZ_B0,
+ [DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_NOVA_12MHZ_B0,
+ [DEVICE_MODE_FM_RADIO] = SMS_FW_FM_RADIO,
+ [DEVICE_MODE_FM_RADIO_BDA] = SMS_FW_FM_RADIO,
+ },
+ [SMS_VEGA] = {
+ [DEVICE_MODE_CMMB] = SMS_FW_CMMB_VEGA_12MHZ,
+ },
+ [SMS_VENICE] = {
+ [DEVICE_MODE_CMMB] = SMS_FW_CMMB_VENICE_12MHZ,
+ },
+ [SMS_MING] = {
+ [DEVICE_MODE_CMMB] = SMS_FW_CMMB_MING_APP,
+ },
+ [SMS_PELE] = {
+ [DEVICE_MODE_ISDBT] = SMS_FW_ISDBT_PELE,
+ [DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_PELE,
+ },
+ [SMS_RIO] = {
+ [DEVICE_MODE_DVBT] = SMS_FW_DVB_RIO,
+ [DEVICE_MODE_DVBH] = SMS_FW_DVBH_RIO,
+ [DEVICE_MODE_DVBT_BDA] = SMS_FW_DVB_RIO,
+ [DEVICE_MODE_ISDBT] = SMS_FW_ISDBT_RIO,
+ [DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_RIO,
+ [DEVICE_MODE_FM_RADIO] = SMS_FW_FM_RADIO_RIO,
+ [DEVICE_MODE_FM_RADIO_BDA] = SMS_FW_FM_RADIO_RIO,
+ },
+ [SMS_DENVER_1530] = {
+ [DEVICE_MODE_ATSC] = SMS_FW_ATSC_DENVER,
+ },
+ [SMS_DENVER_2160] = {
+ [DEVICE_MODE_DAB_TDMB] = SMS_FW_TDMB_DENVER,
+ },
+};
+
+/**
+ * get firmware file name from one of the two mechanisms : sms_boards or
+ * smscore_fw_lkup.
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ * @param mode requested mode of operation
+ * @param lookup if 1, always get the fw filename from smscore_fw_lkup
+ * table. if 0, try first to get from sms_boards
+ *
+ * @return 0 on success, <0 on error.
+ */
+static char *smscore_get_fw_filename(struct smscore_device_t *coredev,
+ int mode)
+{
+ char **fw;
+ int board_id = smscore_get_board_id(coredev);
+ enum sms_device_type_st type;
+
+ type = smscore_registry_gettype(coredev->devpath);
+
+ /* Prevent looking outside the smscore_fw_lkup table */
+ if (type <= SMS_UNKNOWN_TYPE || type >= SMS_NUM_OF_DEVICE_TYPES)
+ return NULL;
+ if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX)
+ return NULL;
+
+ sms_debug("trying to get fw name from sms_boards board_id %d mode %d",
+ board_id, mode);
+ fw = sms_get_board(board_id)->fw;
+ if (!fw || !fw[mode]) {
+ sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d",
+ mode, type);
+ return smscore_fw_lkup[type][mode];
+ }
+
+ return fw[mode];
}
/**
@@ -627,41 +1144,47 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
* @return 0 on success, <0 on error.
*/
static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
- char *filename,
+ int mode,
loadfirmware_t loadfirmware_handler)
{
int rc = -ENOENT;
+ u8 *fw_buf;
+ u32 fw_buf_size;
const struct firmware *fw;
- u8 *fw_buffer;
- if (loadfirmware_handler == NULL && !(coredev->device_flags &
- SMS_DEVICE_FAMILY2))
+ char *fw_filename = smscore_get_fw_filename(coredev, mode);
+ if (!fw_filename) {
+ sms_err("mode %d not supported on this device", mode);
+ return -ENOENT;
+ }
+ sms_debug("Firmware name: %s", fw_filename);
+
+ if (loadfirmware_handler == NULL && !(coredev->device_flags
+ & SMS_DEVICE_FAMILY2))
return -EINVAL;
- rc = request_firmware(&fw, filename, coredev->device);
+ rc = request_firmware(&fw, fw_filename, coredev->device);
if (rc < 0) {
- sms_info("failed to open \"%s\"", filename);
+ sms_err("failed to open firmware file \"%s\"", fw_filename);
return rc;
}
- sms_info("read FW %s, size=%zd", filename, fw->size);
- fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
- GFP_KERNEL | GFP_DMA);
- if (fw_buffer) {
- memcpy(fw_buffer, fw->data, fw->size);
+ sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size);
+ fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
+ GFP_KERNEL | GFP_DMA);
+ if (!fw_buf) {
+ sms_err("failed to allocate firmware buffer");
+ rc = -ENOMEM;
+ } else {
+ memcpy(fw_buf, fw->data, fw->size);
+ fw_buf_size = fw->size;
rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
- smscore_load_firmware_family2(coredev,
- fw_buffer,
- fw->size) :
- loadfirmware_handler(coredev->context,
- fw_buffer, fw->size);
-
- kfree(fw_buffer);
- } else {
- sms_info("failed to allocate firmware buffer");
- rc = -ENOMEM;
+ smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size)
+ : loadfirmware_handler(coredev->context, fw_buf,
+ fw_buf_size);
}
+ kfree(fw_buf);
release_firmware(fw);
return rc;
@@ -703,14 +1226,15 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
if (num_buffers == coredev->num_buffers)
break;
if (++retry > 10) {
- sms_info("exiting although "
- "not all buffers released.");
+ sms_info("exiting although not all buffers released.");
break;
}
sms_info("waiting for %d buffer(s)",
coredev->num_buffers - num_buffers);
+ kmutex_unlock(&g_smscore_deviceslock);
msleep(100);
+ kmutex_lock(&g_smscore_deviceslock);
}
sms_info("freed %d buffers", num_buffers);
@@ -719,8 +1243,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
dma_free_coherent(NULL, coredev->common_buffer_size,
coredev->common_buffer, coredev->common_buffer_phys);
- if (coredev->fw_buf != NULL)
- kfree(coredev->fw_buf);
+ kfree(coredev->fw_buf);
list_del(&coredev->entry);
kfree(coredev);
@@ -733,19 +1256,19 @@ EXPORT_SYMBOL_GPL(smscore_unregister_device);
static int smscore_detect_mode(struct smscore_device_t *coredev)
{
- void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
+ void *buffer = kmalloc(sizeof(struct sms_msg_hdr) + SMS_DMA_ALIGNMENT,
GFP_KERNEL | GFP_DMA);
- struct SmsMsgHdr_ST *msg =
- (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
+ struct sms_msg_hdr *msg =
+ (struct sms_msg_hdr *) SMS_ALIGN_ADDRESS(buffer);
int rc;
if (!buffer)
return -ENOMEM;
SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
- sizeof(struct SmsMsgHdr_ST));
+ sizeof(struct sms_msg_hdr));
- rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
+ rc = smscore_sendrequest_and_wait(coredev, msg, msg->msg_length,
&coredev->version_ex_done);
if (rc == -ETIME) {
sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
@@ -753,11 +1276,11 @@ static int smscore_detect_mode(struct smscore_device_t *coredev)
if (wait_for_completion_timeout(&coredev->resume_done,
msecs_to_jiffies(5000))) {
rc = smscore_sendrequest_and_wait(
- coredev, msg, msg->msgLength,
+ coredev, msg, msg->msg_length,
&coredev->version_ex_done);
if (rc < 0)
- sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
- "second try, rc %d", rc);
+ sms_err("MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d",
+ rc);
} else
rc = -ETIME;
}
@@ -767,31 +1290,39 @@ static int smscore_detect_mode(struct smscore_device_t *coredev)
return rc;
}
-static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
- /*Stellar NOVA A0 Nova B0 VEGA*/
- /*DVBT*/
- {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
- /*DVBH*/
- {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
- /*TDMB*/
- {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
- /*DABIP*/
- {"none", "none", "none", "none"},
- /*BDA*/
- {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
- /*ISDBT*/
- {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
- /*ISDBTBDA*/
- {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
- /*CMMB*/
- {"none", "none", "none", "cmmb_vega_12mhz.inp"}
-};
-
-static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
- int mode, enum sms_device_type_st type)
+/**
+ * send init device request and wait for response
+ *
+ * @param coredev pointer to a coredev object returned by
+ * smscore_register_device
+ * @param mode requested mode of operation
+ *
+ * @return 0 on success, <0 on error.
+ */
+static int smscore_init_device(struct smscore_device_t *coredev, int mode)
{
- char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
- return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
+ void *buffer;
+ struct sms_msg_data *msg;
+ int rc = 0;
+
+ buffer = kmalloc(sizeof(struct sms_msg_data) +
+ SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
+ if (!buffer) {
+ sms_err("Could not allocate buffer for init device message.");
+ return -ENOMEM;
+ }
+
+ msg = (struct sms_msg_data *)SMS_ALIGN_ADDRESS(buffer);
+ SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_INIT_DEVICE_REQ,
+ sizeof(struct sms_msg_data));
+ msg->msg_data[0] = mode;
+
+ rc = smscore_sendrequest_and_wait(coredev, msg,
+ msg->x_msg_header. msg_length,
+ &coredev->init_device_done);
+
+ kfree(buffer);
+ return rc;
}
/**
@@ -806,13 +1337,11 @@ static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
*/
int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
{
- void *buffer;
int rc = 0;
- enum sms_device_type_st type;
sms_debug("set device mode to %d", mode);
if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
- if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
+ if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) {
sms_err("invalid mode specified %d", mode);
return -EINVAL;
}
@@ -833,58 +1362,21 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
}
if (!(coredev->modes_supported & (1 << mode))) {
- char *fw_filename;
-
- type = smscore_registry_gettype(coredev->devpath);
- fw_filename = sms_get_fw_name(coredev, mode, type);
-
rc = smscore_load_firmware_from_file(coredev,
- fw_filename, NULL);
- if (rc < 0) {
- sms_warn("error %d loading firmware: %s, "
- "trying again with default firmware",
- rc, fw_filename);
-
- /* try again with the default firmware */
- fw_filename = smscore_fw_lkup[mode][type];
- rc = smscore_load_firmware_from_file(coredev,
- fw_filename, NULL);
-
- if (rc < 0) {
- sms_warn("error %d loading "
- "firmware: %s", rc,
- fw_filename);
- return rc;
- }
- }
- sms_log("firmware download success: %s", fw_filename);
- } else
- sms_info("mode %d supported by running "
- "firmware", mode);
-
- buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
- SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
- if (buffer) {
- struct SmsMsgData_ST *msg =
- (struct SmsMsgData_ST *)
- SMS_ALIGN_ADDRESS(buffer);
-
- SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
- sizeof(struct SmsMsgData_ST));
- msg->msgData[0] = mode;
-
- rc = smscore_sendrequest_and_wait(
- coredev, msg, msg->xMsgHeader.msgLength,
- &coredev->init_device_done);
-
- kfree(buffer);
+ mode, NULL);
+ if (rc >= 0)
+ sms_info("firmware download success");
} else {
- sms_err("Could not allocate buffer for "
- "init device message.");
- rc = -ENOMEM;
+ sms_info("mode %d is already supported by running firmware",
+ mode);
+ }
+ if (coredev->fw_version >= 0x800) {
+ rc = smscore_init_device(coredev, mode);
+ if (rc < 0)
+ sms_err("device init failed, rc %d.", rc);
}
} else {
- if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
+ if (mode <= DEVICE_MODE_NONE || mode >= DEVICE_MODE_MAX) {
sms_err("invalid mode specified %d", mode);
return -EINVAL;
}
@@ -900,12 +1392,32 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
}
if (rc >= 0) {
+ char *buffer;
coredev->mode = mode;
coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
+
+ buffer = kmalloc(sizeof(struct sms_msg_data) +
+ SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
+ if (buffer) {
+ struct sms_msg_data *msg = (struct sms_msg_data *) SMS_ALIGN_ADDRESS(buffer);
+
+ SMS_INIT_MSG(&msg->x_msg_header, MSG_SMS_INIT_DEVICE_REQ,
+ sizeof(struct sms_msg_data));
+ msg->msg_data[0] = mode;
+
+ rc = smscore_sendrequest_and_wait(
+ coredev, msg, msg->x_msg_header.msg_length,
+ &coredev->init_device_done);
+
+ kfree(buffer);
+ }
}
if (rc < 0)
sms_err("return error code %d.", rc);
+ else
+ sms_debug("Success setting device mode.");
+
return rc;
}
@@ -971,7 +1483,7 @@ found:
*/
void smscore_onresponse(struct smscore_device_t *coredev,
struct smscore_buffer_t *cb) {
- struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
+ struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) ((u8 *) cb->p
+ cb->offset);
struct smscore_client_t *client;
int rc = -EBUSY;
@@ -983,7 +1495,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
last_sample_time = time_now;
if (time_now - last_sample_time > 10000) {
- sms_debug("\ndata rate %d bytes/secs",
+ sms_debug("data rate %d bytes/secs",
(int)((data_total * 1000) /
(time_now - last_sample_time)));
@@ -993,14 +1505,14 @@ void smscore_onresponse(struct smscore_device_t *coredev,
data_total += cb->size;
/* Do we need to re-route? */
- if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) ||
- (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) {
+ if ((phdr->msg_type == MSG_SMS_HO_PER_SLICES_IND) ||
+ (phdr->msg_type == MSG_SMS_TRANSMISSION_IND)) {
if (coredev->mode == DEVICE_MODE_DVBT_BDA)
- phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID;
+ phdr->msg_dst_id = DVBT_BDA_CONTROL_MSG_ID;
}
- client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
+ client = smscore_find_client(coredev, phdr->msg_type, phdr->msg_dst_id);
/* If no client registered for type & id,
* check for control client where type is not registered */
@@ -1008,57 +1520,75 @@ void smscore_onresponse(struct smscore_device_t *coredev,
rc = client->onresponse_handler(client->context, cb);
if (rc < 0) {
- switch (phdr->msgType) {
+ switch (phdr->msg_type) {
+ case MSG_SMS_ISDBT_TUNE_RES:
+ break;
+ case MSG_SMS_RF_TUNE_RES:
+ break;
+ case MSG_SMS_SIGNAL_DETECTED_IND:
+ break;
+ case MSG_SMS_NO_SIGNAL_IND:
+ break;
+ case MSG_SMS_SPI_INT_LINE_SET_RES:
+ break;
+ case MSG_SMS_INTERFACE_LOCK_IND:
+ break;
+ case MSG_SMS_INTERFACE_UNLOCK_IND:
+ break;
case MSG_SMS_GET_VERSION_EX_RES:
{
- struct SmsVersionRes_ST *ver =
- (struct SmsVersionRes_ST *) phdr;
- sms_debug("MSG_SMS_GET_VERSION_EX_RES "
- "id %d prots 0x%x ver %d.%d",
- ver->FirmwareId, ver->SupportedProtocols,
- ver->RomVersionMajor, ver->RomVersionMinor);
-
- coredev->mode = ver->FirmwareId == 255 ?
- DEVICE_MODE_NONE : ver->FirmwareId;
- coredev->modes_supported = ver->SupportedProtocols;
+ struct sms_version_res *ver =
+ (struct sms_version_res *) phdr;
+ sms_debug("Firmware id %d prots 0x%x ver %d.%d",
+ ver->firmware_id, ver->supported_protocols,
+ ver->rom_ver_major, ver->rom_ver_minor);
+
+ coredev->mode = ver->firmware_id == 255 ?
+ DEVICE_MODE_NONE : ver->firmware_id;
+ coredev->modes_supported = ver->supported_protocols;
+ coredev->fw_version = ver->rom_ver_major << 8 |
+ ver->rom_ver_minor;
complete(&coredev->version_ex_done);
break;
}
case MSG_SMS_INIT_DEVICE_RES:
- sms_debug("MSG_SMS_INIT_DEVICE_RES");
complete(&coredev->init_device_done);
break;
case MSG_SW_RELOAD_START_RES:
- sms_debug("MSG_SW_RELOAD_START_RES");
complete(&coredev->reload_start_done);
break;
+ case MSG_SMS_DATA_VALIDITY_RES:
+ {
+ struct sms_msg_data *validity = (struct sms_msg_data *) phdr;
+
+ sms_debug("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x",
+ validity->msg_data[0]);
+ complete(&coredev->data_validity_done);
+ break;
+ }
case MSG_SMS_DATA_DOWNLOAD_RES:
complete(&coredev->data_download_done);
break;
case MSG_SW_RELOAD_EXEC_RES:
- sms_debug("MSG_SW_RELOAD_EXEC_RES");
break;
case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
- sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
complete(&coredev->trigger_done);
break;
case MSG_SMS_SLEEP_RESUME_COMP_IND:
complete(&coredev->resume_done);
break;
case MSG_SMS_GPIO_CONFIG_EX_RES:
- sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
complete(&coredev->gpio_configuration_done);
break;
case MSG_SMS_GPIO_SET_LEVEL_RES:
- sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
complete(&coredev->gpio_set_level_done);
break;
case MSG_SMS_GPIO_GET_LEVEL_RES:
{
u32 *msgdata = (u32 *) phdr;
coredev->gpio_get_res = msgdata[1];
- sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
+ sms_debug("gpio level %d",
coredev->gpio_get_res);
complete(&coredev->gpio_get_level_done);
break;
@@ -1070,12 +1600,24 @@ void smscore_onresponse(struct smscore_device_t *coredev,
sms_ir_event(coredev,
(const char *)
((char *)phdr
- + sizeof(struct SmsMsgHdr_ST)),
- (int)phdr->msgLength
- - sizeof(struct SmsMsgHdr_ST));
+ + sizeof(struct sms_msg_hdr)),
+ (int)phdr->msg_length
+ - sizeof(struct sms_msg_hdr));
+ break;
+
+ case MSG_SMS_DVBT_BDA_DATA:
+ /*
+ * It can be received here, if the frontend is
+ * tuned into a valid channel and the proper firmware
+ * is loaded. That happens when the module got removed
+ * and re-inserted, without powering the device off
+ */
break;
default:
+ sms_debug("message %s(%d) not handled.",
+ smscore_translate_msg(phdr->msg_type),
+ phdr->msg_type);
break;
}
smscore_putbuffer(coredev, cb);
@@ -1092,7 +1634,7 @@ EXPORT_SYMBOL_GPL(smscore_onresponse);
* @return pointer to descriptor on success, NULL on error.
*/
-struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
+static struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
{
struct smscore_buffer_t *cb = NULL;
unsigned long flags;
@@ -1257,7 +1799,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
void *buffer, size_t size)
{
struct smscore_device_t *coredev;
- struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
+ struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) buffer;
int rc;
if (client == NULL) {
@@ -1274,7 +1816,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
}
rc = smscore_validate_client(client->coredev, client, 0,
- phdr->msgSrcId);
+ phdr->msg_src_id);
if (rc < 0)
return rc;
@@ -1288,16 +1830,16 @@ int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
struct smscore_config_gpio *pinconfig)
{
struct {
- struct SmsMsgHdr_ST hdr;
+ struct sms_msg_hdr hdr;
u32 data[6];
} msg;
if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
- msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
- msg.hdr.msgDstId = HIF_TASK;
- msg.hdr.msgFlags = 0;
- msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
- msg.hdr.msgLength = sizeof(msg);
+ msg.hdr.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
+ msg.hdr.msg_dst_id = HIF_TASK;
+ msg.hdr.msg_flags = 0;
+ msg.hdr.msg_type = MSG_SMS_GPIO_CONFIG_EX_REQ;
+ msg.hdr.msg_length = sizeof(msg);
msg.data[0] = pin;
msg.data[1] = pinconfig->pullupdown;
@@ -1306,16 +1848,16 @@ int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
switch (pinconfig->outputdriving) {
- case SMS_GPIO_OUTPUTDRIVING_16mA:
+ case SMS_GPIO_OUTPUTDRIVING_S_16mA:
msg.data[3] = 7; /* Nova - 16mA */
break;
- case SMS_GPIO_OUTPUTDRIVING_12mA:
+ case SMS_GPIO_OUTPUTDRIVING_S_12mA:
msg.data[3] = 5; /* Nova - 11mA */
break;
- case SMS_GPIO_OUTPUTDRIVING_8mA:
+ case SMS_GPIO_OUTPUTDRIVING_S_8mA:
msg.data[3] = 3; /* Nova - 7mA */
break;
- case SMS_GPIO_OUTPUTDRIVING_4mA:
+ case SMS_GPIO_OUTPUTDRIVING_S_4mA:
default:
msg.data[3] = 2; /* Nova - 4mA */
break;
@@ -1333,18 +1875,18 @@ int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
{
struct {
- struct SmsMsgHdr_ST hdr;
+ struct sms_msg_hdr hdr;
u32 data[3];
} msg;
if (pin > MAX_GPIO_PIN_NUMBER)
return -EINVAL;
- msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
- msg.hdr.msgDstId = HIF_TASK;
- msg.hdr.msgFlags = 0;
- msg.hdr.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
- msg.hdr.msgLength = sizeof(msg);
+ msg.hdr.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
+ msg.hdr.msg_dst_id = HIF_TASK;
+ msg.hdr.msg_flags = 0;
+ msg.hdr.msg_type = MSG_SMS_GPIO_SET_LEVEL_REQ;
+ msg.hdr.msg_length = sizeof(msg);
msg.data[0] = pin;
msg.data[1] = level ? 1 : 0;
@@ -1355,122 +1897,121 @@ int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
}
/* new GPIO management implementation */
-static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
- u32 *pGroupNum, u32 *pGroupCfg) {
-
- *pGroupCfg = 1;
-
- if (PinNum <= 1) {
- *pTranslatedPinNum = 0;
- *pGroupNum = 9;
- *pGroupCfg = 2;
- } else if (PinNum >= 2 && PinNum <= 6) {
- *pTranslatedPinNum = 2;
- *pGroupNum = 0;
- *pGroupCfg = 2;
- } else if (PinNum >= 7 && PinNum <= 11) {
- *pTranslatedPinNum = 7;
- *pGroupNum = 1;
- } else if (PinNum >= 12 && PinNum <= 15) {
- *pTranslatedPinNum = 12;
- *pGroupNum = 2;
- *pGroupCfg = 3;
- } else if (PinNum == 16) {
- *pTranslatedPinNum = 16;
- *pGroupNum = 23;
- } else if (PinNum >= 17 && PinNum <= 24) {
- *pTranslatedPinNum = 17;
- *pGroupNum = 3;
- } else if (PinNum == 25) {
- *pTranslatedPinNum = 25;
- *pGroupNum = 6;
- } else if (PinNum >= 26 && PinNum <= 28) {
- *pTranslatedPinNum = 26;
- *pGroupNum = 4;
- } else if (PinNum == 29) {
- *pTranslatedPinNum = 29;
- *pGroupNum = 5;
- *pGroupCfg = 2;
- } else if (PinNum == 30) {
- *pTranslatedPinNum = 30;
- *pGroupNum = 8;
- } else if (PinNum == 31) {
- *pTranslatedPinNum = 31;
- *pGroupNum = 17;
+static int get_gpio_pin_params(u32 pin_num, u32 *p_translatedpin_num,
+ u32 *p_group_num, u32 *p_group_cfg) {
+
+ *p_group_cfg = 1;
+
+ if (pin_num <= 1) {
+ *p_translatedpin_num = 0;
+ *p_group_num = 9;
+ *p_group_cfg = 2;
+ } else if (pin_num >= 2 && pin_num <= 6) {
+ *p_translatedpin_num = 2;
+ *p_group_num = 0;
+ *p_group_cfg = 2;
+ } else if (pin_num >= 7 && pin_num <= 11) {
+ *p_translatedpin_num = 7;
+ *p_group_num = 1;
+ } else if (pin_num >= 12 && pin_num <= 15) {
+ *p_translatedpin_num = 12;
+ *p_group_num = 2;
+ *p_group_cfg = 3;
+ } else if (pin_num == 16) {
+ *p_translatedpin_num = 16;
+ *p_group_num = 23;
+ } else if (pin_num >= 17 && pin_num <= 24) {
+ *p_translatedpin_num = 17;
+ *p_group_num = 3;
+ } else if (pin_num == 25) {
+ *p_translatedpin_num = 25;
+ *p_group_num = 6;
+ } else if (pin_num >= 26 && pin_num <= 28) {
+ *p_translatedpin_num = 26;
+ *p_group_num = 4;
+ } else if (pin_num == 29) {
+ *p_translatedpin_num = 29;
+ *p_group_num = 5;
+ *p_group_cfg = 2;
+ } else if (pin_num == 30) {
+ *p_translatedpin_num = 30;
+ *p_group_num = 8;
+ } else if (pin_num == 31) {
+ *p_translatedpin_num = 31;
+ *p_group_num = 17;
} else
return -1;
- *pGroupCfg <<= 24;
+ *p_group_cfg <<= 24;
return 0;
}
-int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
- struct smscore_gpio_config *pGpioConfig) {
+int smscore_gpio_configure(struct smscore_device_t *coredev, u8 pin_num,
+ struct smscore_config_gpio *p_gpio_config) {
- u32 totalLen;
- u32 TranslatedPinNum = 0;
- u32 GroupNum = 0;
- u32 ElectricChar;
- u32 groupCfg;
+ u32 total_len;
+ u32 translatedpin_num = 0;
+ u32 group_num = 0;
+ u32 electric_char;
+ u32 group_cfg;
void *buffer;
int rc;
- struct SetGpioMsg {
- struct SmsMsgHdr_ST xMsgHeader;
- u32 msgData[6];
- } *pMsg;
+ struct set_gpio_msg {
+ struct sms_msg_hdr x_msg_header;
+ u32 msg_data[6];
+ } *p_msg;
- if (PinNum > MAX_GPIO_PIN_NUMBER)
+ if (pin_num > MAX_GPIO_PIN_NUMBER)
return -EINVAL;
- if (pGpioConfig == NULL)
+ if (p_gpio_config == NULL)
return -EINVAL;
- totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
+ total_len = sizeof(struct sms_msg_hdr) + (sizeof(u32) * 6);
- buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+ buffer = kmalloc(total_len + SMS_DMA_ALIGNMENT,
GFP_KERNEL | GFP_DMA);
if (!buffer)
return -ENOMEM;
- pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+ p_msg = (struct set_gpio_msg *) SMS_ALIGN_ADDRESS(buffer);
- pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
- pMsg->xMsgHeader.msgDstId = HIF_TASK;
- pMsg->xMsgHeader.msgFlags = 0;
- pMsg->xMsgHeader.msgLength = (u16) totalLen;
- pMsg->msgData[0] = PinNum;
+ p_msg->x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
+ p_msg->x_msg_header.msg_dst_id = HIF_TASK;
+ p_msg->x_msg_header.msg_flags = 0;
+ p_msg->x_msg_header.msg_length = (u16) total_len;
+ p_msg->msg_data[0] = pin_num;
if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
- pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
- if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
- &groupCfg) != 0) {
+ p_msg->x_msg_header.msg_type = MSG_SMS_GPIO_CONFIG_REQ;
+ if (get_gpio_pin_params(pin_num, &translatedpin_num, &group_num,
+ &group_cfg) != 0) {
rc = -EINVAL;
goto free;
}
- pMsg->msgData[1] = TranslatedPinNum;
- pMsg->msgData[2] = GroupNum;
- ElectricChar = (pGpioConfig->PullUpDown)
- | (pGpioConfig->InputCharacteristics << 2)
- | (pGpioConfig->OutputSlewRate << 3)
- | (pGpioConfig->OutputDriving << 4);
- pMsg->msgData[3] = ElectricChar;
- pMsg->msgData[4] = pGpioConfig->Direction;
- pMsg->msgData[5] = groupCfg;
+ p_msg->msg_data[1] = translatedpin_num;
+ p_msg->msg_data[2] = group_num;
+ electric_char = (p_gpio_config->pullupdown)
+ | (p_gpio_config->inputcharacteristics << 2)
+ | (p_gpio_config->outputslewrate << 3)
+ | (p_gpio_config->outputdriving << 4);
+ p_msg->msg_data[3] = electric_char;
+ p_msg->msg_data[4] = p_gpio_config->direction;
+ p_msg->msg_data[5] = group_cfg;
} else {
- pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
- pMsg->msgData[1] = pGpioConfig->PullUpDown;
- pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
- pMsg->msgData[3] = pGpioConfig->OutputDriving;
- pMsg->msgData[4] = pGpioConfig->Direction;
- pMsg->msgData[5] = 0;
+ p_msg->x_msg_header.msg_type = MSG_SMS_GPIO_CONFIG_EX_REQ;
+ p_msg->msg_data[1] = p_gpio_config->pullupdown;
+ p_msg->msg_data[2] = p_gpio_config->outputslewrate;
+ p_msg->msg_data[3] = p_gpio_config->outputdriving;
+ p_msg->msg_data[4] = p_gpio_config->direction;
+ p_msg->msg_data[5] = 0;
}
- smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
- rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+ rc = smscore_sendrequest_and_wait(coredev, p_msg, total_len,
&coredev->gpio_configuration_done);
if (rc != 0) {
@@ -1485,42 +2026,41 @@ free:
return rc;
}
-int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
- u8 NewLevel) {
+int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 pin_num,
+ u8 new_level) {
- u32 totalLen;
+ u32 total_len;
int rc;
void *buffer;
- struct SetGpioMsg {
- struct SmsMsgHdr_ST xMsgHeader;
- u32 msgData[3]; /* keep it 3 ! */
- } *pMsg;
+ struct set_gpio_msg {
+ struct sms_msg_hdr x_msg_header;
+ u32 msg_data[3]; /* keep it 3 ! */
+ } *p_msg;
- if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER))
+ if ((new_level > 1) || (pin_num > MAX_GPIO_PIN_NUMBER))
return -EINVAL;
- totalLen = sizeof(struct SmsMsgHdr_ST) +
+ total_len = sizeof(struct sms_msg_hdr) +
(3 * sizeof(u32)); /* keep it 3 ! */
- buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+ buffer = kmalloc(total_len + SMS_DMA_ALIGNMENT,
GFP_KERNEL | GFP_DMA);
if (!buffer)
return -ENOMEM;
- pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+ p_msg = (struct set_gpio_msg *) SMS_ALIGN_ADDRESS(buffer);
- pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
- pMsg->xMsgHeader.msgDstId = HIF_TASK;
- pMsg->xMsgHeader.msgFlags = 0;
- pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
- pMsg->xMsgHeader.msgLength = (u16) totalLen;
- pMsg->msgData[0] = PinNum;
- pMsg->msgData[1] = NewLevel;
+ p_msg->x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
+ p_msg->x_msg_header.msg_dst_id = HIF_TASK;
+ p_msg->x_msg_header.msg_flags = 0;
+ p_msg->x_msg_header.msg_type = MSG_SMS_GPIO_SET_LEVEL_REQ;
+ p_msg->x_msg_header.msg_length = (u16) total_len;
+ p_msg->msg_data[0] = pin_num;
+ p_msg->msg_data[1] = new_level;
/* Send message to SMS */
- smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
- rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+ rc = smscore_sendrequest_and_wait(coredev, p_msg, total_len,
&coredev->gpio_set_level_done);
if (rc != 0) {
@@ -1534,42 +2074,41 @@ int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
return rc;
}
-int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
+int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 pin_num,
u8 *level) {
- u32 totalLen;
+ u32 total_len;
int rc;
void *buffer;
- struct SetGpioMsg {
- struct SmsMsgHdr_ST xMsgHeader;
- u32 msgData[2];
- } *pMsg;
+ struct set_gpio_msg {
+ struct sms_msg_hdr x_msg_header;
+ u32 msg_data[2];
+ } *p_msg;
- if (PinNum > MAX_GPIO_PIN_NUMBER)
+ if (pin_num > MAX_GPIO_PIN_NUMBER)
return -EINVAL;
- totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
+ total_len = sizeof(struct sms_msg_hdr) + (2 * sizeof(u32));
- buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
+ buffer = kmalloc(total_len + SMS_DMA_ALIGNMENT,
GFP_KERNEL | GFP_DMA);
if (!buffer)
return -ENOMEM;
- pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
+ p_msg = (struct set_gpio_msg *) SMS_ALIGN_ADDRESS(buffer);
- pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
- pMsg->xMsgHeader.msgDstId = HIF_TASK;
- pMsg->xMsgHeader.msgFlags = 0;
- pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
- pMsg->xMsgHeader.msgLength = (u16) totalLen;
- pMsg->msgData[0] = PinNum;
- pMsg->msgData[1] = 0;
+ p_msg->x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
+ p_msg->x_msg_header.msg_dst_id = HIF_TASK;
+ p_msg->x_msg_header.msg_flags = 0;
+ p_msg->x_msg_header.msg_type = MSG_SMS_GPIO_GET_LEVEL_REQ;
+ p_msg->x_msg_header.msg_length = (u16) total_len;
+ p_msg->msg_data[0] = pin_num;
+ p_msg->msg_data[1] = 0;
/* Send message to SMS */
- smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
- rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
+ rc = smscore_sendrequest_and_wait(coredev, p_msg, total_len,
&coredev->gpio_get_level_done);
if (rc != 0) {
@@ -1635,3 +2174,27 @@ module_exit(smscore_module_exit);
MODULE_DESCRIPTION("Siano MDTV Core module");
MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
MODULE_LICENSE("GPL");
+
+/* This should match what's defined at smscoreapi.h */
+MODULE_FIRMWARE(SMS_FW_ATSC_DENVER);
+MODULE_FIRMWARE(SMS_FW_CMMB_MING_APP);
+MODULE_FIRMWARE(SMS_FW_CMMB_VEGA_12MHZ);
+MODULE_FIRMWARE(SMS_FW_CMMB_VENICE_12MHZ);
+MODULE_FIRMWARE(SMS_FW_DVBH_RIO);
+MODULE_FIRMWARE(SMS_FW_DVB_NOVA_12MHZ_B0);
+MODULE_FIRMWARE(SMS_FW_DVB_NOVA_12MHZ);
+MODULE_FIRMWARE(SMS_FW_DVB_RIO);
+MODULE_FIRMWARE(SMS_FW_FM_RADIO);
+MODULE_FIRMWARE(SMS_FW_FM_RADIO_RIO);
+MODULE_FIRMWARE(SMS_FW_DVBT_HCW_55XXX);
+MODULE_FIRMWARE(SMS_FW_ISDBT_HCW_55XXX);
+MODULE_FIRMWARE(SMS_FW_ISDBT_NOVA_12MHZ_B0);
+MODULE_FIRMWARE(SMS_FW_ISDBT_NOVA_12MHZ);
+MODULE_FIRMWARE(SMS_FW_ISDBT_PELE);
+MODULE_FIRMWARE(SMS_FW_ISDBT_RIO);
+MODULE_FIRMWARE(SMS_FW_DVBT_NOVA_A);
+MODULE_FIRMWARE(SMS_FW_DVBT_NOVA_B);
+MODULE_FIRMWARE(SMS_FW_DVBT_STELLAR);
+MODULE_FIRMWARE(SMS_FW_TDMB_DENVER);
+MODULE_FIRMWARE(SMS_FW_TDMB_NOVA_12MHZ_B0);
+MODULE_FIRMWARE(SMS_FW_TDMB_NOVA_12MHZ);
diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h
index c592ae09039..9c9063cd320 100644
--- a/drivers/media/common/siano/smscoreapi.h
+++ b/drivers/media/common/siano/smscoreapi.h
@@ -40,9 +40,33 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define kmutex_trylock(_p_) mutex_trylock(_p_)
#define kmutex_unlock(_p_) mutex_unlock(_p_)
-#ifndef min
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-#endif
+/*
+ * Define the firmware names used by the driver.
+ * Those should match what's used at smscoreapi.c and sms-cards.c
+ * including the MODULE_FIRMWARE() macros at the end of smscoreapi.c
+ */
+#define SMS_FW_ATSC_DENVER "atsc_denver.inp"
+#define SMS_FW_CMMB_MING_APP "cmmb_ming_app.inp"
+#define SMS_FW_CMMB_VEGA_12MHZ "cmmb_vega_12mhz.inp"
+#define SMS_FW_CMMB_VENICE_12MHZ "cmmb_venice_12mhz.inp"
+#define SMS_FW_DVBH_RIO "dvbh_rio.inp"
+#define SMS_FW_DVB_NOVA_12MHZ_B0 "dvb_nova_12mhz_b0.inp"
+#define SMS_FW_DVB_NOVA_12MHZ "dvb_nova_12mhz.inp"
+#define SMS_FW_DVB_RIO "dvb_rio.inp"
+#define SMS_FW_FM_RADIO "fm_radio.inp"
+#define SMS_FW_FM_RADIO_RIO "fm_radio_rio.inp"
+#define SMS_FW_DVBT_HCW_55XXX "sms1xxx-hcw-55xxx-dvbt-02.fw"
+#define SMS_FW_ISDBT_HCW_55XXX "sms1xxx-hcw-55xxx-isdbt-02.fw"
+#define SMS_FW_ISDBT_NOVA_12MHZ_B0 "isdbt_nova_12mhz_b0.inp"
+#define SMS_FW_ISDBT_NOVA_12MHZ "isdbt_nova_12mhz.inp"
+#define SMS_FW_ISDBT_PELE "isdbt_pele.inp"
+#define SMS_FW_ISDBT_RIO "isdbt_rio.inp"
+#define SMS_FW_DVBT_NOVA_A "sms1xxx-nova-a-dvbt-01.fw"
+#define SMS_FW_DVBT_NOVA_B "sms1xxx-nova-b-dvbt-01.fw"
+#define SMS_FW_DVBT_STELLAR "sms1xxx-stellar-dvbt-01.fw"
+#define SMS_FW_TDMB_DENVER "tdmb_denver.inp"
+#define SMS_FW_TDMB_NOVA_12MHZ_B0 "tdmb_nova_12mhz_b0.inp"
+#define SMS_FW_TDMB_NOVA_12MHZ "tdmb_nova_12mhz.inp"
#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000)
#define SMS_ALLOC_ALIGNMENT 128
@@ -50,18 +74,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define SMS_ALIGN_ADDRESS(addr) \
((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
+#define SMS_DEVICE_FAMILY1 0
#define SMS_DEVICE_FAMILY2 1
#define SMS_ROM_NO_RESPONSE 2
#define SMS_DEVICE_NOT_READY 0x8000000
enum sms_device_type_st {
+ SMS_UNKNOWN_TYPE = -1,
SMS_STELLAR = 0,
SMS_NOVA_A0,
SMS_NOVA_B0,
SMS_VEGA,
+ SMS_VENICE,
+ SMS_MING,
+ SMS_PELE,
+ SMS_RIO,
+ SMS_DENVER_1530,
+ SMS_DENVER_2160,
SMS_NUM_OF_DEVICE_TYPES
};
+enum sms_power_mode_st {
+ SMS_POWER_MODE_ACTIVE,
+ SMS_POWER_MODE_SUSPENDED
+};
+
struct smscore_device_t;
struct smscore_client_t;
struct smscore_buffer_t;
@@ -149,6 +186,7 @@ struct smscore_device_t {
/* host <--> device messages */
struct completion version_ex_done, data_download_done, trigger_done;
+ struct completion data_validity_done, device_ready_done;
struct completion init_device_done, reload_start_done, resume_done;
struct completion gpio_configuration_done, gpio_set_level_done;
struct completion gpio_get_level_done, ir_init_done;
@@ -165,10 +203,17 @@ struct smscore_device_t {
/* Firmware */
u8 *fw_buf;
u32 fw_buf_size;
+ u16 fw_version;
/* Infrared (IR) */
struct ir_t ir;
+ /*
+ * Identify if device is USB or not.
+ * Used by smsdvb-sysfs to know the root node for debugfs
+ */
+ bool is_usb_device;
+
int led_state;
};
@@ -176,81 +221,363 @@ struct smscore_device_t {
#define SMS_ANTENNA_GPIO_0 1
#define SMS_ANTENNA_GPIO_1 0
-#define BW_8_MHZ 0
-#define BW_7_MHZ 1
-#define BW_6_MHZ 2
-#define BW_5_MHZ 3
-#define BW_ISDBT_1SEG 4
-#define BW_ISDBT_3SEG 5
+enum sms_bandwidth_mode {
+ BW_8_MHZ = 0,
+ BW_7_MHZ = 1,
+ BW_6_MHZ = 2,
+ BW_5_MHZ = 3,
+ BW_ISDBT_1SEG = 4,
+ BW_ISDBT_3SEG = 5,
+ BW_2_MHZ = 6,
+ BW_FM_RADIO = 7,
+ BW_ISDBT_13SEG = 8,
+ BW_1_5_MHZ = 15,
+ BW_UNKNOWN = 0xffff
+};
+
#define MSG_HDR_FLAG_SPLIT_MSG 4
#define MAX_GPIO_PIN_NUMBER 31
#define HIF_TASK 11
+#define HIF_TASK_SLAVE 22
+#define HIF_TASK_SLAVE2 33
+#define HIF_TASK_SLAVE3 44
#define SMS_HOST_LIB 150
#define DVBT_BDA_CONTROL_MSG_ID 201
#define SMS_MAX_PAYLOAD_SIZE 240
#define SMS_TUNE_TIMEOUT 500
-#define MSG_SMS_GPIO_CONFIG_REQ 507
-#define MSG_SMS_GPIO_CONFIG_RES 508
-#define MSG_SMS_GPIO_SET_LEVEL_REQ 509
-#define MSG_SMS_GPIO_SET_LEVEL_RES 510
-#define MSG_SMS_GPIO_GET_LEVEL_REQ 511
-#define MSG_SMS_GPIO_GET_LEVEL_RES 512
-#define MSG_SMS_RF_TUNE_REQ 561
-#define MSG_SMS_RF_TUNE_RES 562
-#define MSG_SMS_INIT_DEVICE_REQ 578
-#define MSG_SMS_INIT_DEVICE_RES 579
-#define MSG_SMS_ADD_PID_FILTER_REQ 601
-#define MSG_SMS_ADD_PID_FILTER_RES 602
-#define MSG_SMS_REMOVE_PID_FILTER_REQ 603
-#define MSG_SMS_REMOVE_PID_FILTER_RES 604
-#define MSG_SMS_DAB_CHANNEL 607
-#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608
-#define MSG_SMS_GET_PID_FILTER_LIST_RES 609
-#define MSG_SMS_GET_STATISTICS_RES 616
-#define MSG_SMS_GET_STATISTICS_REQ 615
-#define MSG_SMS_HO_PER_SLICES_IND 630
-#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651
-#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652
-#define MSG_SMS_SLEEP_RESUME_COMP_IND 655
-#define MSG_SMS_DATA_DOWNLOAD_REQ 660
-#define MSG_SMS_DATA_DOWNLOAD_RES 661
-#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664
-#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665
-#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666
-#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667
-#define MSG_SMS_GET_VERSION_EX_REQ 668
-#define MSG_SMS_GET_VERSION_EX_RES 669
-#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670
-#define MSG_SMS_I2C_SET_FREQ_REQ 685
-#define MSG_SMS_GENERIC_I2C_REQ 687
-#define MSG_SMS_GENERIC_I2C_RES 688
-#define MSG_SMS_DVBT_BDA_DATA 693
-#define MSG_SW_RELOAD_REQ 697
-#define MSG_SMS_DATA_MSG 699
-#define MSG_SW_RELOAD_START_REQ 702
-#define MSG_SW_RELOAD_START_RES 703
-#define MSG_SW_RELOAD_EXEC_REQ 704
-#define MSG_SW_RELOAD_EXEC_RES 705
-#define MSG_SMS_SPI_INT_LINE_SET_REQ 710
-#define MSG_SMS_GPIO_CONFIG_EX_REQ 712
-#define MSG_SMS_GPIO_CONFIG_EX_RES 713
-#define MSG_SMS_ISDBT_TUNE_REQ 776
-#define MSG_SMS_ISDBT_TUNE_RES 777
-#define MSG_SMS_TRANSMISSION_IND 782
-#define MSG_SMS_START_IR_REQ 800
-#define MSG_SMS_START_IR_RES 801
-#define MSG_SMS_IR_SAMPLES_IND 802
-#define MSG_SMS_SIGNAL_DETECTED_IND 827
-#define MSG_SMS_NO_SIGNAL_IND 828
+enum msg_types {
+ MSG_TYPE_BASE_VAL = 500,
+ MSG_SMS_GET_VERSION_REQ = 503,
+ MSG_SMS_GET_VERSION_RES = 504,
+ MSG_SMS_MULTI_BRIDGE_CFG = 505,
+ MSG_SMS_GPIO_CONFIG_REQ = 507,
+ MSG_SMS_GPIO_CONFIG_RES = 508,
+ MSG_SMS_GPIO_SET_LEVEL_REQ = 509,
+ MSG_SMS_GPIO_SET_LEVEL_RES = 510,
+ MSG_SMS_GPIO_GET_LEVEL_REQ = 511,
+ MSG_SMS_GPIO_GET_LEVEL_RES = 512,
+ MSG_SMS_EEPROM_BURN_IND = 513,
+ MSG_SMS_LOG_ENABLE_CHANGE_REQ = 514,
+ MSG_SMS_LOG_ENABLE_CHANGE_RES = 515,
+ MSG_SMS_SET_MAX_TX_MSG_LEN_REQ = 516,
+ MSG_SMS_SET_MAX_TX_MSG_LEN_RES = 517,
+ MSG_SMS_SPI_HALFDUPLEX_TOKEN_HOST_TO_DEVICE = 518,
+ MSG_SMS_SPI_HALFDUPLEX_TOKEN_DEVICE_TO_HOST = 519,
+ MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_REQ = 520,
+ MSG_SMS_BACKGROUND_SCAN_FLAG_CHANGE_RES = 521,
+ MSG_SMS_BACKGROUND_SCAN_SIGNAL_DETECTED_IND = 522,
+ MSG_SMS_BACKGROUND_SCAN_NO_SIGNAL_IND = 523,
+ MSG_SMS_CONFIGURE_RF_SWITCH_REQ = 524,
+ MSG_SMS_CONFIGURE_RF_SWITCH_RES = 525,
+ MSG_SMS_MRC_PATH_DISCONNECT_REQ = 526,
+ MSG_SMS_MRC_PATH_DISCONNECT_RES = 527,
+ MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_REQ = 528,
+ MSG_SMS_RECEIVE_1SEG_THROUGH_FULLSEG_RES = 529,
+ MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_REQ = 530,
+ MSG_SMS_RECEIVE_VHF_VIA_VHF_INPUT_RES = 531,
+ MSG_WR_REG_RFT_REQ = 533,
+ MSG_WR_REG_RFT_RES = 534,
+ MSG_RD_REG_RFT_REQ = 535,
+ MSG_RD_REG_RFT_RES = 536,
+ MSG_RD_REG_ALL_RFT_REQ = 537,
+ MSG_RD_REG_ALL_RFT_RES = 538,
+ MSG_HELP_INT = 539,
+ MSG_RUN_SCRIPT_INT = 540,
+ MSG_SMS_EWS_INBAND_REQ = 541,
+ MSG_SMS_EWS_INBAND_RES = 542,
+ MSG_SMS_RFS_SELECT_REQ = 543,
+ MSG_SMS_RFS_SELECT_RES = 544,
+ MSG_SMS_MB_GET_VER_REQ = 545,
+ MSG_SMS_MB_GET_VER_RES = 546,
+ MSG_SMS_MB_WRITE_CFGFILE_REQ = 547,
+ MSG_SMS_MB_WRITE_CFGFILE_RES = 548,
+ MSG_SMS_MB_READ_CFGFILE_REQ = 549,
+ MSG_SMS_MB_READ_CFGFILE_RES = 550,
+ MSG_SMS_RD_MEM_REQ = 552,
+ MSG_SMS_RD_MEM_RES = 553,
+ MSG_SMS_WR_MEM_REQ = 554,
+ MSG_SMS_WR_MEM_RES = 555,
+ MSG_SMS_UPDATE_MEM_REQ = 556,
+ MSG_SMS_UPDATE_MEM_RES = 557,
+ MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_REQ = 558,
+ MSG_SMS_ISDBT_ENABLE_FULL_PARAMS_SET_RES = 559,
+ MSG_SMS_RF_TUNE_REQ = 561,
+ MSG_SMS_RF_TUNE_RES = 562,
+ MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_REQ = 563,
+ MSG_SMS_ISDBT_ENABLE_HIGH_MOBILITY_RES = 564,
+ MSG_SMS_ISDBT_SB_RECEPTION_REQ = 565,
+ MSG_SMS_ISDBT_SB_RECEPTION_RES = 566,
+ MSG_SMS_GENERIC_EPROM_WRITE_REQ = 567,
+ MSG_SMS_GENERIC_EPROM_WRITE_RES = 568,
+ MSG_SMS_GENERIC_EPROM_READ_REQ = 569,
+ MSG_SMS_GENERIC_EPROM_READ_RES = 570,
+ MSG_SMS_EEPROM_WRITE_REQ = 571,
+ MSG_SMS_EEPROM_WRITE_RES = 572,
+ MSG_SMS_CUSTOM_READ_REQ = 574,
+ MSG_SMS_CUSTOM_READ_RES = 575,
+ MSG_SMS_CUSTOM_WRITE_REQ = 576,
+ MSG_SMS_CUSTOM_WRITE_RES = 577,
+ MSG_SMS_INIT_DEVICE_REQ = 578,
+ MSG_SMS_INIT_DEVICE_RES = 579,
+ MSG_SMS_ATSC_SET_ALL_IP_REQ = 580,
+ MSG_SMS_ATSC_SET_ALL_IP_RES = 581,
+ MSG_SMS_ATSC_START_ENSEMBLE_REQ = 582,
+ MSG_SMS_ATSC_START_ENSEMBLE_RES = 583,
+ MSG_SMS_SET_OUTPUT_MODE_REQ = 584,
+ MSG_SMS_SET_OUTPUT_MODE_RES = 585,
+ MSG_SMS_ATSC_IP_FILTER_GET_LIST_REQ = 586,
+ MSG_SMS_ATSC_IP_FILTER_GET_LIST_RES = 587,
+ MSG_SMS_SUB_CHANNEL_START_REQ = 589,
+ MSG_SMS_SUB_CHANNEL_START_RES = 590,
+ MSG_SMS_SUB_CHANNEL_STOP_REQ = 591,
+ MSG_SMS_SUB_CHANNEL_STOP_RES = 592,
+ MSG_SMS_ATSC_IP_FILTER_ADD_REQ = 593,
+ MSG_SMS_ATSC_IP_FILTER_ADD_RES = 594,
+ MSG_SMS_ATSC_IP_FILTER_REMOVE_REQ = 595,
+ MSG_SMS_ATSC_IP_FILTER_REMOVE_RES = 596,
+ MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_REQ = 597,
+ MSG_SMS_ATSC_IP_FILTER_REMOVE_ALL_RES = 598,
+ MSG_SMS_WAIT_CMD = 599,
+ MSG_SMS_ADD_PID_FILTER_REQ = 601,
+ MSG_SMS_ADD_PID_FILTER_RES = 602,
+ MSG_SMS_REMOVE_PID_FILTER_REQ = 603,
+ MSG_SMS_REMOVE_PID_FILTER_RES = 604,
+ MSG_SMS_FAST_INFORMATION_CHANNEL_REQ = 605,
+ MSG_SMS_FAST_INFORMATION_CHANNEL_RES = 606,
+ MSG_SMS_DAB_CHANNEL = 607,
+ MSG_SMS_GET_PID_FILTER_LIST_REQ = 608,
+ MSG_SMS_GET_PID_FILTER_LIST_RES = 609,
+ MSG_SMS_POWER_DOWN_REQ = 610,
+ MSG_SMS_POWER_DOWN_RES = 611,
+ MSG_SMS_ATSC_SLT_EXIST_IND = 612,
+ MSG_SMS_ATSC_NO_SLT_IND = 613,
+ MSG_SMS_GET_STATISTICS_REQ = 615,
+ MSG_SMS_GET_STATISTICS_RES = 616,
+ MSG_SMS_SEND_DUMP = 617,
+ MSG_SMS_SCAN_START_REQ = 618,
+ MSG_SMS_SCAN_START_RES = 619,
+ MSG_SMS_SCAN_STOP_REQ = 620,
+ MSG_SMS_SCAN_STOP_RES = 621,
+ MSG_SMS_SCAN_PROGRESS_IND = 622,
+ MSG_SMS_SCAN_COMPLETE_IND = 623,
+ MSG_SMS_LOG_ITEM = 624,
+ MSG_SMS_DAB_SUBCHANNEL_RECONFIG_REQ = 628,
+ MSG_SMS_DAB_SUBCHANNEL_RECONFIG_RES = 629,
+ MSG_SMS_HO_PER_SLICES_IND = 630,
+ MSG_SMS_HO_INBAND_POWER_IND = 631,
+ MSG_SMS_MANUAL_DEMOD_REQ = 632,
+ MSG_SMS_HO_TUNE_ON_REQ = 636,
+ MSG_SMS_HO_TUNE_ON_RES = 637,
+ MSG_SMS_HO_TUNE_OFF_REQ = 638,
+ MSG_SMS_HO_TUNE_OFF_RES = 639,
+ MSG_SMS_HO_PEEK_FREQ_REQ = 640,
+ MSG_SMS_HO_PEEK_FREQ_RES = 641,
+ MSG_SMS_HO_PEEK_FREQ_IND = 642,
+ MSG_SMS_MB_ATTEN_SET_REQ = 643,
+ MSG_SMS_MB_ATTEN_SET_RES = 644,
+ MSG_SMS_ENABLE_STAT_IN_I2C_REQ = 649,
+ MSG_SMS_ENABLE_STAT_IN_I2C_RES = 650,
+ MSG_SMS_SET_ANTENNA_CONFIG_REQ = 651,
+ MSG_SMS_SET_ANTENNA_CONFIG_RES = 652,
+ MSG_SMS_GET_STATISTICS_EX_REQ = 653,
+ MSG_SMS_GET_STATISTICS_EX_RES = 654,
+ MSG_SMS_SLEEP_RESUME_COMP_IND = 655,
+ MSG_SMS_SWITCH_HOST_INTERFACE_REQ = 656,
+ MSG_SMS_SWITCH_HOST_INTERFACE_RES = 657,
+ MSG_SMS_DATA_DOWNLOAD_REQ = 660,
+ MSG_SMS_DATA_DOWNLOAD_RES = 661,
+ MSG_SMS_DATA_VALIDITY_REQ = 662,
+ MSG_SMS_DATA_VALIDITY_RES = 663,
+ MSG_SMS_SWDOWNLOAD_TRIGGER_REQ = 664,
+ MSG_SMS_SWDOWNLOAD_TRIGGER_RES = 665,
+ MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ = 666,
+ MSG_SMS_SWDOWNLOAD_BACKDOOR_RES = 667,
+ MSG_SMS_GET_VERSION_EX_REQ = 668,
+ MSG_SMS_GET_VERSION_EX_RES = 669,
+ MSG_SMS_CLOCK_OUTPUT_CONFIG_REQ = 670,
+ MSG_SMS_CLOCK_OUTPUT_CONFIG_RES = 671,
+ MSG_SMS_I2C_SET_FREQ_REQ = 685,
+ MSG_SMS_I2C_SET_FREQ_RES = 686,
+ MSG_SMS_GENERIC_I2C_REQ = 687,
+ MSG_SMS_GENERIC_I2C_RES = 688,
+ MSG_SMS_DVBT_BDA_DATA = 693,
+ MSG_SW_RELOAD_REQ = 697,
+ MSG_SMS_DATA_MSG = 699,
+ MSG_TABLE_UPLOAD_REQ = 700,
+ MSG_TABLE_UPLOAD_RES = 701,
+ MSG_SW_RELOAD_START_REQ = 702,
+ MSG_SW_RELOAD_START_RES = 703,
+ MSG_SW_RELOAD_EXEC_REQ = 704,
+ MSG_SW_RELOAD_EXEC_RES = 705,
+ MSG_SMS_SPI_INT_LINE_SET_REQ = 710,
+ MSG_SMS_SPI_INT_LINE_SET_RES = 711,
+ MSG_SMS_GPIO_CONFIG_EX_REQ = 712,
+ MSG_SMS_GPIO_CONFIG_EX_RES = 713,
+ MSG_SMS_WATCHDOG_ACT_REQ = 716,
+ MSG_SMS_WATCHDOG_ACT_RES = 717,
+ MSG_SMS_LOOPBACK_REQ = 718,
+ MSG_SMS_LOOPBACK_RES = 719,
+ MSG_SMS_RAW_CAPTURE_START_REQ = 720,
+ MSG_SMS_RAW_CAPTURE_START_RES = 721,
+ MSG_SMS_RAW_CAPTURE_ABORT_REQ = 722,
+ MSG_SMS_RAW_CAPTURE_ABORT_RES = 723,
+ MSG_SMS_RAW_CAPTURE_COMPLETE_IND = 728,
+ MSG_SMS_DATA_PUMP_IND = 729,
+ MSG_SMS_DATA_PUMP_REQ = 730,
+ MSG_SMS_DATA_PUMP_RES = 731,
+ MSG_SMS_FLASH_DL_REQ = 732,
+ MSG_SMS_EXEC_TEST_1_REQ = 734,
+ MSG_SMS_EXEC_TEST_1_RES = 735,
+ MSG_SMS_ENBALE_TS_INTERFACE_REQ = 736,
+ MSG_SMS_ENBALE_TS_INTERFACE_RES = 737,
+ MSG_SMS_SPI_SET_BUS_WIDTH_REQ = 738,
+ MSG_SMS_SPI_SET_BUS_WIDTH_RES = 739,
+ MSG_SMS_SEND_EMM_REQ = 740,
+ MSG_SMS_SEND_EMM_RES = 741,
+ MSG_SMS_DISABLE_TS_INTERFACE_REQ = 742,
+ MSG_SMS_DISABLE_TS_INTERFACE_RES = 743,
+ MSG_SMS_IS_BUF_FREE_REQ = 744,
+ MSG_SMS_IS_BUF_FREE_RES = 745,
+ MSG_SMS_EXT_ANTENNA_REQ = 746,
+ MSG_SMS_EXT_ANTENNA_RES = 747,
+ MSG_SMS_CMMB_GET_NET_OF_FREQ_REQ_OBSOLETE = 748,
+ MSG_SMS_CMMB_GET_NET_OF_FREQ_RES_OBSOLETE = 749,
+ MSG_SMS_BATTERY_LEVEL_REQ = 750,
+ MSG_SMS_BATTERY_LEVEL_RES = 751,
+ MSG_SMS_CMMB_INJECT_TABLE_REQ_OBSOLETE = 752,
+ MSG_SMS_CMMB_INJECT_TABLE_RES_OBSOLETE = 753,
+ MSG_SMS_FM_RADIO_BLOCK_IND = 754,
+ MSG_SMS_HOST_NOTIFICATION_IND = 755,
+ MSG_SMS_CMMB_GET_CONTROL_TABLE_REQ_OBSOLETE = 756,
+ MSG_SMS_CMMB_GET_CONTROL_TABLE_RES_OBSOLETE = 757,
+ MSG_SMS_CMMB_GET_NETWORKS_REQ = 760,
+ MSG_SMS_CMMB_GET_NETWORKS_RES = 761,
+ MSG_SMS_CMMB_START_SERVICE_REQ = 762,
+ MSG_SMS_CMMB_START_SERVICE_RES = 763,
+ MSG_SMS_CMMB_STOP_SERVICE_REQ = 764,
+ MSG_SMS_CMMB_STOP_SERVICE_RES = 765,
+ MSG_SMS_CMMB_ADD_CHANNEL_FILTER_REQ = 768,
+ MSG_SMS_CMMB_ADD_CHANNEL_FILTER_RES = 769,
+ MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_REQ = 770,
+ MSG_SMS_CMMB_REMOVE_CHANNEL_FILTER_RES = 771,
+ MSG_SMS_CMMB_START_CONTROL_INFO_REQ = 772,
+ MSG_SMS_CMMB_START_CONTROL_INFO_RES = 773,
+ MSG_SMS_CMMB_STOP_CONTROL_INFO_REQ = 774,
+ MSG_SMS_CMMB_STOP_CONTROL_INFO_RES = 775,
+ MSG_SMS_ISDBT_TUNE_REQ = 776,
+ MSG_SMS_ISDBT_TUNE_RES = 777,
+ MSG_SMS_TRANSMISSION_IND = 782,
+ MSG_SMS_PID_STATISTICS_IND = 783,
+ MSG_SMS_POWER_DOWN_IND = 784,
+ MSG_SMS_POWER_DOWN_CONF = 785,
+ MSG_SMS_POWER_UP_IND = 786,
+ MSG_SMS_POWER_UP_CONF = 787,
+ MSG_SMS_POWER_MODE_SET_REQ = 790,
+ MSG_SMS_POWER_MODE_SET_RES = 791,
+ MSG_SMS_DEBUG_HOST_EVENT_REQ = 792,
+ MSG_SMS_DEBUG_HOST_EVENT_RES = 793,
+ MSG_SMS_NEW_CRYSTAL_REQ = 794,
+ MSG_SMS_NEW_CRYSTAL_RES = 795,
+ MSG_SMS_CONFIG_SPI_REQ = 796,
+ MSG_SMS_CONFIG_SPI_RES = 797,
+ MSG_SMS_I2C_SHORT_STAT_IND = 798,
+ MSG_SMS_START_IR_REQ = 800,
+ MSG_SMS_START_IR_RES = 801,
+ MSG_SMS_IR_SAMPLES_IND = 802,
+ MSG_SMS_CMMB_CA_SERVICE_IND = 803,
+ MSG_SMS_SLAVE_DEVICE_DETECTED = 804,
+ MSG_SMS_INTERFACE_LOCK_IND = 805,
+ MSG_SMS_INTERFACE_UNLOCK_IND = 806,
+ MSG_SMS_SEND_ROSUM_BUFF_REQ = 810,
+ MSG_SMS_SEND_ROSUM_BUFF_RES = 811,
+ MSG_SMS_ROSUM_BUFF = 812,
+ MSG_SMS_SET_AES128_KEY_REQ = 815,
+ MSG_SMS_SET_AES128_KEY_RES = 816,
+ MSG_SMS_MBBMS_WRITE_REQ = 817,
+ MSG_SMS_MBBMS_WRITE_RES = 818,
+ MSG_SMS_MBBMS_READ_IND = 819,
+ MSG_SMS_IQ_STREAM_START_REQ = 820,
+ MSG_SMS_IQ_STREAM_START_RES = 821,
+ MSG_SMS_IQ_STREAM_STOP_REQ = 822,
+ MSG_SMS_IQ_STREAM_STOP_RES = 823,
+ MSG_SMS_IQ_STREAM_DATA_BLOCK = 824,
+ MSG_SMS_GET_EEPROM_VERSION_REQ = 825,
+ MSG_SMS_GET_EEPROM_VERSION_RES = 826,
+ MSG_SMS_SIGNAL_DETECTED_IND = 827,
+ MSG_SMS_NO_SIGNAL_IND = 828,
+ MSG_SMS_MRC_SHUTDOWN_SLAVE_REQ = 830,
+ MSG_SMS_MRC_SHUTDOWN_SLAVE_RES = 831,
+ MSG_SMS_MRC_BRINGUP_SLAVE_REQ = 832,
+ MSG_SMS_MRC_BRINGUP_SLAVE_RES = 833,
+ MSG_SMS_EXTERNAL_LNA_CTRL_REQ = 834,
+ MSG_SMS_EXTERNAL_LNA_CTRL_RES = 835,
+ MSG_SMS_SET_PERIODIC_STATISTICS_REQ = 836,
+ MSG_SMS_SET_PERIODIC_STATISTICS_RES = 837,
+ MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_REQ = 838,
+ MSG_SMS_CMMB_SET_AUTO_OUTPUT_TS0_RES = 839,
+ LOCAL_TUNE = 850,
+ LOCAL_IFFT_H_ICI = 851,
+ MSG_RESYNC_REQ = 852,
+ MSG_SMS_CMMB_GET_MRC_STATISTICS_REQ = 853,
+ MSG_SMS_CMMB_GET_MRC_STATISTICS_RES = 854,
+ MSG_SMS_LOG_EX_ITEM = 855,
+ MSG_SMS_DEVICE_DATA_LOSS_IND = 856,
+ MSG_SMS_MRC_WATCHDOG_TRIGGERED_IND = 857,
+ MSG_SMS_USER_MSG_REQ = 858,
+ MSG_SMS_USER_MSG_RES = 859,
+ MSG_SMS_SMART_CARD_INIT_REQ = 860,
+ MSG_SMS_SMART_CARD_INIT_RES = 861,
+ MSG_SMS_SMART_CARD_WRITE_REQ = 862,
+ MSG_SMS_SMART_CARD_WRITE_RES = 863,
+ MSG_SMS_SMART_CARD_READ_IND = 864,
+ MSG_SMS_TSE_ENABLE_REQ = 866,
+ MSG_SMS_TSE_ENABLE_RES = 867,
+ MSG_SMS_CMMB_GET_SHORT_STATISTICS_REQ = 868,
+ MSG_SMS_CMMB_GET_SHORT_STATISTICS_RES = 869,
+ MSG_SMS_LED_CONFIG_REQ = 870,
+ MSG_SMS_LED_CONFIG_RES = 871,
+ MSG_PWM_ANTENNA_REQ = 872,
+ MSG_PWM_ANTENNA_RES = 873,
+ MSG_SMS_CMMB_SMD_SN_REQ = 874,
+ MSG_SMS_CMMB_SMD_SN_RES = 875,
+ MSG_SMS_CMMB_SET_CA_CW_REQ = 876,
+ MSG_SMS_CMMB_SET_CA_CW_RES = 877,
+ MSG_SMS_CMMB_SET_CA_SALT_REQ = 878,
+ MSG_SMS_CMMB_SET_CA_SALT_RES = 879,
+ MSG_SMS_NSCD_INIT_REQ = 880,
+ MSG_SMS_NSCD_INIT_RES = 881,
+ MSG_SMS_NSCD_PROCESS_SECTION_REQ = 882,
+ MSG_SMS_NSCD_PROCESS_SECTION_RES = 883,
+ MSG_SMS_DBD_CREATE_OBJECT_REQ = 884,
+ MSG_SMS_DBD_CREATE_OBJECT_RES = 885,
+ MSG_SMS_DBD_CONFIGURE_REQ = 886,
+ MSG_SMS_DBD_CONFIGURE_RES = 887,
+ MSG_SMS_DBD_SET_KEYS_REQ = 888,
+ MSG_SMS_DBD_SET_KEYS_RES = 889,
+ MSG_SMS_DBD_PROCESS_HEADER_REQ = 890,
+ MSG_SMS_DBD_PROCESS_HEADER_RES = 891,
+ MSG_SMS_DBD_PROCESS_DATA_REQ = 892,
+ MSG_SMS_DBD_PROCESS_DATA_RES = 893,
+ MSG_SMS_DBD_PROCESS_GET_DATA_REQ = 894,
+ MSG_SMS_DBD_PROCESS_GET_DATA_RES = 895,
+ MSG_SMS_NSCD_OPEN_SESSION_REQ = 896,
+ MSG_SMS_NSCD_OPEN_SESSION_RES = 897,
+ MSG_SMS_SEND_HOST_DATA_TO_DEMUX_REQ = 898,
+ MSG_SMS_SEND_HOST_DATA_TO_DEMUX_RES = 899,
+ MSG_LAST_MSG_TYPE = 900,
+};
#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
- (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
- (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
+ (ptr)->msg_type = type; \
+ (ptr)->msg_src_id = src; \
+ (ptr)->msg_dst_id = dst; \
+ (ptr)->msg_length = len; \
+ (ptr)->msg_flags = 0; \
} while (0)
#define SMS_INIT_MSG(ptr, type, len) \
@@ -277,228 +604,296 @@ enum SMS_DEVICE_MODE {
DEVICE_MODE_ISDBT_BDA,
DEVICE_MODE_CMMB,
DEVICE_MODE_RAW_TUNER,
+ DEVICE_MODE_FM_RADIO,
+ DEVICE_MODE_FM_RADIO_BDA,
+ DEVICE_MODE_ATSC,
DEVICE_MODE_MAX,
};
-struct SmsMsgHdr_ST {
- u16 msgType;
- u8 msgSrcId;
- u8 msgDstId;
- u16 msgLength; /* Length of entire message, including header */
- u16 msgFlags;
+struct sms_msg_hdr {
+ u16 msg_type;
+ u8 msg_src_id;
+ u8 msg_dst_id;
+ u16 msg_length; /* length of entire message, including header */
+ u16 msg_flags;
+};
+
+struct sms_msg_data {
+ struct sms_msg_hdr x_msg_header;
+ u32 msg_data[1];
};
-struct SmsMsgData_ST {
- struct SmsMsgHdr_ST xMsgHeader;
- u32 msgData[1];
+struct sms_msg_data2 {
+ struct sms_msg_hdr x_msg_header;
+ u32 msg_data[2];
};
-struct SmsMsgData_ST2 {
- struct SmsMsgHdr_ST xMsgHeader;
- u32 msgData[2];
+struct sms_msg_data4 {
+ struct sms_msg_hdr x_msg_header;
+ u32 msg_data[4];
};
-struct SmsDataDownload_ST {
- struct SmsMsgHdr_ST xMsgHeader;
- u32 MemAddr;
- u8 Payload[SMS_MAX_PAYLOAD_SIZE];
+struct sms_data_download {
+ struct sms_msg_hdr x_msg_header;
+ u32 mem_addr;
+ u8 payload[SMS_MAX_PAYLOAD_SIZE];
};
-struct SmsVersionRes_ST {
- struct SmsMsgHdr_ST xMsgHeader;
+struct sms_version_res {
+ struct sms_msg_hdr x_msg_header;
- u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
- u8 Step; /* 0 - Step A */
- u8 MetalFix; /* 0 - Metal 0 */
+ u16 chip_model; /* e.g. 0x1102 for SMS-1102 "Nova" */
+ u8 step; /* 0 - step A */
+ u8 metal_fix; /* 0 - Metal 0 */
- /* FirmwareId 0xFF if ROM, otherwise the
+ /* firmware_id 0xFF if ROM, otherwise the
* value indicated by SMSHOSTLIB_DEVICE_MODES_E */
- u8 FirmwareId;
- /* SupportedProtocols Bitwise OR combination of
+ u8 firmware_id;
+ /* supported_protocols Bitwise OR combination of
* supported protocols */
- u8 SupportedProtocols;
+ u8 supported_protocols;
- u8 VersionMajor;
- u8 VersionMinor;
- u8 VersionPatch;
- u8 VersionFieldPatch;
+ u8 version_major;
+ u8 version_minor;
+ u8 version_patch;
+ u8 version_field_patch;
- u8 RomVersionMajor;
- u8 RomVersionMinor;
- u8 RomVersionPatch;
- u8 RomVersionFieldPatch;
+ u8 rom_ver_major;
+ u8 rom_ver_minor;
+ u8 rom_ver_patch;
+ u8 rom_ver_field_patch;
u8 TextLabel[34];
};
-struct SmsFirmware_ST {
- u32 CheckSum;
- u32 Length;
- u32 StartAddress;
- u8 Payload[1];
+struct sms_firmware {
+ u32 check_sum;
+ u32 length;
+ u32 start_address;
+ u8 payload[1];
};
-/* Statistics information returned as response for
- * SmsHostApiGetStatistics_Req */
-struct SMSHOSTLIB_STATISTICS_ST {
- u32 Reserved; /* Reserved */
+/* statistics information returned as response for
+ * SmsHostApiGetstatistics_Req */
+struct sms_stats {
+ u32 reserved; /* reserved */
/* Common parameters */
- u32 IsRfLocked; /* 0 - not locked, 1 - locked */
- u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
- u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
+ u32 is_rf_locked; /* 0 - not locked, 1 - locked */
+ u32 is_demod_locked; /* 0 - not locked, 1 - locked */
+ u32 is_external_lna_on; /* 0 - external LNA off, 1 - external LNA on */
/* Reception quality */
s32 SNR; /* dB */
- u32 BER; /* Post Viterbi BER [1E-5] */
+ u32 ber; /* Post Viterbi ber [1E-5] */
u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */
- u32 TS_PER; /* Transport stream PER,
+ u32 ts_per; /* Transport stream PER,
0xFFFFFFFF indicate N/A, valid only for DVB-T/H */
u32 MFER; /* DVB-H frame error rate in percentage,
0xFFFFFFFF indicate N/A, valid only for DVB-H */
s32 RSSI; /* dBm */
- s32 InBandPwr; /* In band power in dBM */
- s32 CarrierOffset; /* Carrier Offset in bin/1024 */
+ s32 in_band_pwr; /* In band power in dBM */
+ s32 carrier_offset; /* Carrier Offset in bin/1024 */
/* Transmission parameters */
- u32 Frequency; /* Frequency in Hz */
- u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */
- u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4,
+ u32 frequency; /* frequency in Hz */
+ u32 bandwidth; /* bandwidth in MHz, valid only for DVB-T/H */
+ u32 transmission_mode; /* Transmission Mode, for DAB modes 1-4,
for DVB-T/H FFT mode carriers in Kilos */
- u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET,
+ u32 modem_state; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET,
valid only for DVB-T/H */
- u32 GuardInterval; /* Guard Interval from
- SMSHOSTLIB_GUARD_INTERVALS_ET, valid only for DVB-T/H */
- u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
+ u32 guard_interval; /* Guard Interval from
+ SMSHOSTLIB_GUARD_INTERVALS_ET, valid only for DVB-T/H */
+ u32 code_rate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
valid only for DVB-T/H */
- u32 LPCodeRate; /* Low Priority Code Rate from
+ u32 lp_code_rate; /* Low Priority Code Rate from
SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */
- u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET,
+ u32 hierarchy; /* hierarchy from SMSHOSTLIB_HIERARCHY_ET,
valid only for DVB-T/H */
- u32 Constellation; /* Constellation from
+ u32 constellation; /* constellation from
SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */
/* Burst parameters, valid only for DVB-H */
- u32 BurstSize; /* Current burst size in bytes,
+ u32 burst_size; /* Current burst size in bytes,
valid only for DVB-H */
- u32 BurstDuration; /* Current burst duration in mSec,
+ u32 burst_duration; /* Current burst duration in mSec,
valid only for DVB-H */
- u32 BurstCycleTime; /* Current burst cycle time in mSec,
+ u32 burst_cycle_time; /* Current burst cycle time in mSec,
valid only for DVB-H */
- u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec,
+ u32 calc_burst_cycle_time;/* Current burst cycle time in mSec,
as calculated by demodulator, valid only for DVB-H */
- u32 NumOfRows; /* Number of rows in MPE table,
+ u32 num_of_rows; /* Number of rows in MPE table,
valid only for DVB-H */
- u32 NumOfPaddCols; /* Number of padding columns in MPE table,
+ u32 num_of_padd_cols; /* Number of padding columns in MPE table,
valid only for DVB-H */
- u32 NumOfPunctCols; /* Number of puncturing columns in MPE table,
+ u32 num_of_punct_cols; /* Number of puncturing columns in MPE table,
valid only for DVB-H */
- u32 ErrorTSPackets; /* Number of erroneous
+ u32 error_ts_packets; /* Number of erroneous
transport-stream packets */
- u32 TotalTSPackets; /* Total number of transport-stream packets */
- u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include
+ u32 total_ts_packets; /* Total number of transport-stream packets */
+ u32 num_of_valid_mpe_tlbs; /* Number of MPE tables which do not include
errors after MPE RS decoding */
- u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors
+ u32 num_of_invalid_mpe_tlbs;/* Number of MPE tables which include errors
after MPE RS decoding */
- u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were
+ u32 num_of_corrected_mpe_tlbs;/* Number of MPE tables which were
corrected by MPE RS decoding */
/* Common params */
- u32 BERErrorCount; /* Number of errornous SYNC bits. */
- u32 BERBitCount; /* Total number of SYNC bits. */
+ u32 ber_error_count; /* Number of errornous SYNC bits. */
+ u32 ber_bit_count; /* Total number of SYNC bits. */
/* Interface information */
- u32 SmsToHostTxErrors; /* Total number of transmission errors. */
+ u32 sms_to_host_tx_errors; /* Total number of transmission errors. */
/* DAB/T-DMB */
- u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
+ u32 pre_ber; /* DAB/T-DMB only: Pre Viterbi ber [1E-5] */
/* DVB-H TPS parameters */
- u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
+ u32 cell_id; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
if set to 0xFFFFFFFF cell_id not yet recovered */
- u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 -
+ u32 dvbh_srv_ind_hp; /* DVB-H service indication info, bit 1 -
Time Slicing indicator, bit 0 - MPE-FEC indicator */
- u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 -
+ u32 dvbh_srv_ind_lp; /* DVB-H service indication info, bit 1 -
Time Slicing indicator, bit 0 - MPE-FEC indicator */
- u32 NumMPEReceived; /* DVB-H, Num MPE section received */
+ u32 num_mpe_received; /* DVB-H, Num MPE section received */
- u32 ReservedFields[10]; /* Reserved */
+ u32 reservedFields[10]; /* reserved */
};
-struct SmsMsgStatisticsInfo_ST {
- u32 RequestResult;
+struct sms_msg_statistics_info {
+ u32 request_result;
- struct SMSHOSTLIB_STATISTICS_ST Stat;
+ struct sms_stats stat;
/* Split the calc of the SNR in DAB */
- u32 Signal; /* dB */
- u32 Noise; /* dB */
+ u32 signal; /* dB */
+ u32 noise; /* dB */
};
-struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
+struct sms_isdbt_layer_stats {
/* Per-layer information */
- u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
+ u32 code_rate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
* 255 means layer does not exist */
- u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
+ u32 constellation; /* constellation from SMSHOSTLIB_CONSTELLATION_ET,
* 255 means layer does not exist */
- u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
- u32 BERErrorCount; /* Post Viterbi Error Bits Count */
- u32 BERBitCount; /* Post Viterbi Total Bits Count */
- u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
- u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
- u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
- u32 TotalTSPackets; /* Total number of transport-stream packets */
- u32 TILdepthI; /* Time interleaver depth I parameter,
+ u32 ber; /* Post Viterbi ber [1E-5], 0xFFFFFFFF indicate N/A */
+ u32 ber_error_count; /* Post Viterbi Error Bits Count */
+ u32 ber_bit_count; /* Post Viterbi Total Bits Count */
+ u32 pre_ber; /* Pre Viterbi ber [1E-5], 0xFFFFFFFF indicate N/A */
+ u32 ts_per; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
+ u32 error_ts_packets; /* Number of erroneous transport-stream packets */
+ u32 total_ts_packets; /* Total number of transport-stream packets */
+ u32 ti_ldepth_i; /* Time interleaver depth I parameter,
* 255 means layer does not exist */
- u32 NumberOfSegments; /* Number of segments in layer A,
+ u32 number_of_segments; /* Number of segments in layer A,
* 255 means layer does not exist */
- u32 TMCCErrors; /* TMCC errors */
+ u32 tmcc_errors; /* TMCC errors */
};
-struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
- u32 StatisticsType; /* Enumerator identifying the type of the
+struct sms_isdbt_stats {
+ u32 statistics_type; /* Enumerator identifying the type of the
* structure. Values are the same as
* SMSHOSTLIB_DEVICE_MODES_E
*
* This field MUST always be first in any
* statistics structure */
- u32 FullSize; /* Total size of the structure returned by the modem.
+ u32 full_size; /* Total size of the structure returned by the modem.
* If the size requested by the host is smaller than
- * FullSize, the struct will be truncated */
+ * full_size, the struct will be truncated */
/* Common parameters */
- u32 IsRfLocked; /* 0 - not locked, 1 - locked */
- u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
- u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
+ u32 is_rf_locked; /* 0 - not locked, 1 - locked */
+ u32 is_demod_locked; /* 0 - not locked, 1 - locked */
+ u32 is_external_lna_on; /* 0 - external LNA off, 1 - external LNA on */
/* Reception quality */
s32 SNR; /* dB */
s32 RSSI; /* dBm */
- s32 InBandPwr; /* In band power in dBM */
- s32 CarrierOffset; /* Carrier Offset in Hz */
+ s32 in_band_pwr; /* In band power in dBM */
+ s32 carrier_offset; /* Carrier Offset in Hz */
/* Transmission parameters */
- u32 Frequency; /* Frequency in Hz */
- u32 Bandwidth; /* Bandwidth in MHz */
- u32 TransmissionMode; /* ISDB-T transmission mode */
- u32 ModemState; /* 0 - Acquisition, 1 - Locked */
- u32 GuardInterval; /* Guard Interval, 1 divided by value */
- u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
- u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
- u32 NumOfLayers; /* Number of ISDB-T layers in the network */
+ u32 frequency; /* frequency in Hz */
+ u32 bandwidth; /* bandwidth in MHz */
+ u32 transmission_mode; /* ISDB-T transmission mode */
+ u32 modem_state; /* 0 - Acquisition, 1 - Locked */
+ u32 guard_interval; /* Guard Interval, 1 divided by value */
+ u32 system_type; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
+ u32 partial_reception; /* TRUE - partial reception, FALSE otherwise */
+ u32 num_of_layers; /* Number of ISDB-T layers in the network */
/* Per-layer information */
/* Layers A, B and C */
- struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3];
- /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
+ struct sms_isdbt_layer_stats layer_info[3];
+ /* Per-layer statistics, see sms_isdbt_layer_stats */
/* Interface information */
- u32 SmsToHostTxErrors; /* Total number of transmission errors. */
+ u32 sms_to_host_tx_errors; /* Total number of transmission errors. */
};
-struct PID_STATISTICS_DATA_S {
+struct sms_isdbt_stats_ex {
+ u32 statistics_type; /* Enumerator identifying the type of the
+ * structure. Values are the same as
+ * SMSHOSTLIB_DEVICE_MODES_E
+ *
+ * This field MUST always be first in any
+ * statistics structure */
+
+ u32 full_size; /* Total size of the structure returned by the modem.
+ * If the size requested by the host is smaller than
+ * full_size, the struct will be truncated */
+
+ /* Common parameters */
+ u32 is_rf_locked; /* 0 - not locked, 1 - locked */
+ u32 is_demod_locked; /* 0 - not locked, 1 - locked */
+ u32 is_external_lna_on; /* 0 - external LNA off, 1 - external LNA on */
+
+ /* Reception quality */
+ s32 SNR; /* dB */
+ s32 RSSI; /* dBm */
+ s32 in_band_pwr; /* In band power in dBM */
+ s32 carrier_offset; /* Carrier Offset in Hz */
+
+ /* Transmission parameters */
+ u32 frequency; /* frequency in Hz */
+ u32 bandwidth; /* bandwidth in MHz */
+ u32 transmission_mode; /* ISDB-T transmission mode */
+ u32 modem_state; /* 0 - Acquisition, 1 - Locked */
+ u32 guard_interval; /* Guard Interval, 1 divided by value */
+ u32 system_type; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
+ u32 partial_reception; /* TRUE - partial reception, FALSE otherwise */
+ u32 num_of_layers; /* Number of ISDB-T layers in the network */
+
+ u32 segment_number; /* Segment number for ISDB-Tsb */
+ u32 tune_bw; /* Tuned bandwidth - BW_ISDBT_1SEG / BW_ISDBT_3SEG */
+
+ /* Per-layer information */
+ /* Layers A, B and C */
+ struct sms_isdbt_layer_stats layer_info[3];
+ /* Per-layer statistics, see sms_isdbt_layer_stats */
+
+ /* Interface information */
+ u32 reserved1; /* Was sms_to_host_tx_errors - obsolete . */
+ /* Proprietary information */
+ u32 ext_antenna; /* Obsolete field. */
+ u32 reception_quality;
+ u32 ews_alert_active; /* signals if EWS alert is currently on */
+ u32 lna_on_off; /* Internal LNA state: 0: OFF, 1: ON */
+
+ u32 rf_agc_level; /* RF AGC Level [linear units], full gain = 65535 (20dB) */
+ u32 bb_agc_level; /* Baseband AGC level [linear units], full gain = 65535 (71.5dB) */
+ u32 fw_errors_counter; /* Application errors - should be always zero */
+ u8 FwErrorsHistoryArr[8]; /* Last FW errors IDs - first is most recent, last is oldest */
+
+ s32 MRC_SNR; /* dB */
+ u32 snr_full_res; /* dB x 65536 */
+ u32 reserved4[4];
+};
+
+
+struct sms_pid_stats_data {
struct PID_BURST_S {
u32 size;
u32 padding_cols;
@@ -513,112 +908,155 @@ struct PID_STATISTICS_DATA_S {
u32 tot_cor_tbl;
};
-struct PID_DATA_S {
+struct sms_pid_data {
u32 pid;
u32 num_rows;
- struct PID_STATISTICS_DATA_S pid_statistics;
+ struct sms_pid_stats_data pid_statistics;
};
#define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1)
-#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth)
+#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.bandwidth = 8 - _stat.bandwidth)
#define CORRECT_STAT_TRANSMISSON_MODE(_stat) \
- if (_stat.TransmissionMode == 0) \
- _stat.TransmissionMode = 2; \
- else if (_stat.TransmissionMode == 1) \
- _stat.TransmissionMode = 8; \
+ if (_stat.transmission_mode == 0) \
+ _stat.transmission_mode = 2; \
+ else if (_stat.transmission_mode == 1) \
+ _stat.transmission_mode = 8; \
else \
- _stat.TransmissionMode = 4;
+ _stat.transmission_mode = 4;
-struct TRANSMISSION_STATISTICS_S {
- u32 Frequency; /* Frequency in Hz */
- u32 Bandwidth; /* Bandwidth in MHz */
- u32 TransmissionMode; /* FFT mode carriers in Kilos */
- u32 GuardInterval; /* Guard Interval from
+struct sms_tx_stats {
+ u32 frequency; /* frequency in Hz */
+ u32 bandwidth; /* bandwidth in MHz */
+ u32 transmission_mode; /* FFT mode carriers in Kilos */
+ u32 guard_interval; /* Guard Interval from
SMSHOSTLIB_GUARD_INTERVALS_ET */
- u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
- u32 LPCodeRate; /* Low Priority Code Rate from
+ u32 code_rate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
+ u32 lp_code_rate; /* Low Priority Code Rate from
SMSHOSTLIB_CODE_RATE_ET */
- u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */
- u32 Constellation; /* Constellation from
+ u32 hierarchy; /* hierarchy from SMSHOSTLIB_HIERARCHY_ET */
+ u32 constellation; /* constellation from
SMSHOSTLIB_CONSTELLATION_ET */
/* DVB-H TPS parameters */
- u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
+ u32 cell_id; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
if set to 0xFFFFFFFF cell_id not yet recovered */
- u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 -
+ u32 dvbh_srv_ind_hp; /* DVB-H service indication info, bit 1 -
Time Slicing indicator, bit 0 - MPE-FEC indicator */
- u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 -
+ u32 dvbh_srv_ind_lp; /* DVB-H service indication info, bit 1 -
Time Slicing indicator, bit 0 - MPE-FEC indicator */
- u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
+ u32 is_demod_locked; /* 0 - not locked, 1 - locked */
+};
+
+struct sms_rx_stats {
+ u32 is_rf_locked; /* 0 - not locked, 1 - locked */
+ u32 is_demod_locked; /* 0 - not locked, 1 - locked */
+ u32 is_external_lna_on; /* 0 - external LNA off, 1 - external LNA on */
+
+ u32 modem_state; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
+ s32 SNR; /* dB */
+ u32 ber; /* Post Viterbi ber [1E-5] */
+ u32 ber_error_count; /* Number of erroneous SYNC bits. */
+ u32 ber_bit_count; /* Total number of SYNC bits. */
+ u32 ts_per; /* Transport stream PER,
+ 0xFFFFFFFF indicate N/A */
+ u32 MFER; /* DVB-H frame error rate in percentage,
+ 0xFFFFFFFF indicate N/A, valid only for DVB-H */
+ s32 RSSI; /* dBm */
+ s32 in_band_pwr; /* In band power in dBM */
+ s32 carrier_offset; /* Carrier Offset in bin/1024 */
+ u32 error_ts_packets; /* Number of erroneous
+ transport-stream packets */
+ u32 total_ts_packets; /* Total number of transport-stream packets */
+
+ s32 MRC_SNR; /* dB */
+ s32 MRC_RSSI; /* dBm */
+ s32 mrc_in_band_pwr; /* In band power in dBM */
};
-struct RECEPTION_STATISTICS_S {
- u32 IsRfLocked; /* 0 - not locked, 1 - locked */
- u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
- u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
+struct sms_rx_stats_ex {
+ u32 is_rf_locked; /* 0 - not locked, 1 - locked */
+ u32 is_demod_locked; /* 0 - not locked, 1 - locked */
+ u32 is_external_lna_on; /* 0 - external LNA off, 1 - external LNA on */
- u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
+ u32 modem_state; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
s32 SNR; /* dB */
- u32 BER; /* Post Viterbi BER [1E-5] */
- u32 BERErrorCount; /* Number of erronous SYNC bits. */
- u32 BERBitCount; /* Total number of SYNC bits. */
- u32 TS_PER; /* Transport stream PER,
+ u32 ber; /* Post Viterbi ber [1E-5] */
+ u32 ber_error_count; /* Number of erroneous SYNC bits. */
+ u32 ber_bit_count; /* Total number of SYNC bits. */
+ u32 ts_per; /* Transport stream PER,
0xFFFFFFFF indicate N/A */
u32 MFER; /* DVB-H frame error rate in percentage,
0xFFFFFFFF indicate N/A, valid only for DVB-H */
s32 RSSI; /* dBm */
- s32 InBandPwr; /* In band power in dBM */
- s32 CarrierOffset; /* Carrier Offset in bin/1024 */
- u32 ErrorTSPackets; /* Number of erroneous
+ s32 in_band_pwr; /* In band power in dBM */
+ s32 carrier_offset; /* Carrier Offset in bin/1024 */
+ u32 error_ts_packets; /* Number of erroneous
transport-stream packets */
- u32 TotalTSPackets; /* Total number of transport-stream packets */
+ u32 total_ts_packets; /* Total number of transport-stream packets */
+
+ s32 ref_dev_ppm;
+ s32 freq_dev_hz;
s32 MRC_SNR; /* dB */
s32 MRC_RSSI; /* dBm */
- s32 MRC_InBandPwr; /* In band power in dBM */
+ s32 mrc_in_band_pwr; /* In band power in dBM */
};
-/* Statistics information returned as response for
- * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */
-struct SMSHOSTLIB_STATISTICS_DVB_S {
+/* statistics information returned as response for
+ * SmsHostApiGetstatisticsEx_Req for DVB applications, SMS1100 and up */
+struct sms_stats_dvb {
/* Reception */
- struct RECEPTION_STATISTICS_S ReceptionData;
+ struct sms_rx_stats reception_data;
/* Transmission parameters */
- struct TRANSMISSION_STATISTICS_S TransmissionData;
+ struct sms_tx_stats transmission_data;
/* Burst parameters, valid only for DVB-H */
#define SRVM_MAX_PID_FILTERS 8
- struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS];
+ struct sms_pid_data pid_data[SRVM_MAX_PID_FILTERS];
};
-struct SRVM_SIGNAL_STATUS_S {
+/* statistics information returned as response for
+ * SmsHostApiGetstatisticsEx_Req for DVB applications, SMS1100 and up */
+struct sms_stats_dvb_ex {
+ /* Reception */
+ struct sms_rx_stats_ex reception_data;
+
+ /* Transmission parameters */
+ struct sms_tx_stats transmission_data;
+
+ /* Burst parameters, valid only for DVB-H */
+#define SRVM_MAX_PID_FILTERS 8
+ struct sms_pid_data pid_data[SRVM_MAX_PID_FILTERS];
+};
+
+struct sms_srvm_signal_status {
u32 result;
u32 snr;
- u32 tsPackets;
- u32 etsPackets;
+ u32 ts_packets;
+ u32 ets_packets;
u32 constellation;
- u32 hpCode;
- u32 tpsSrvIndLP;
- u32 tpsSrvIndHP;
- u32 cellId;
+ u32 hp_code;
+ u32 tps_srv_ind_lp;
+ u32 tps_srv_ind_hp;
+ u32 cell_id;
u32 reason;
- s32 inBandPower;
- u32 requestId;
+ s32 in_band_power;
+ u32 request_id;
};
-struct SMSHOSTLIB_I2C_REQ_ST {
- u32 DeviceAddress; /* I2c device address */
- u32 WriteCount; /* number of bytes to write */
- u32 ReadCount; /* number of bytes to read */
+struct sms_i2c_req {
+ u32 device_address; /* I2c device address */
+ u32 write_count; /* number of bytes to write */
+ u32 read_count; /* number of bytes to read */
u8 Data[1];
};
-struct SMSHOSTLIB_I2C_RES_ST {
- u32 Status; /* non-zero value in case of failure */
- u32 ReadCount; /* number of bytes read */
+struct sms_i2c_res {
+ u32 status; /* non-zero value in case of failure */
+ u32 read_count; /* number of bytes read */
u8 Data[1];
};
@@ -638,59 +1076,39 @@ struct smscore_config_gpio {
#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
u8 inputcharacteristics;
-#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
-#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
- u8 outputslewrate;
-
-#define SMS_GPIO_OUTPUTDRIVING_4mA 0
-#define SMS_GPIO_OUTPUTDRIVING_8mA 1
-#define SMS_GPIO_OUTPUTDRIVING_12mA 2
-#define SMS_GPIO_OUTPUTDRIVING_16mA 3
- u8 outputdriving;
-};
-
-struct smscore_gpio_config {
-#define SMS_GPIO_DIRECTION_INPUT 0
-#define SMS_GPIO_DIRECTION_OUTPUT 1
- u8 Direction;
-
-#define SMS_GPIO_PULL_UP_DOWN_NONE 0
-#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1
-#define SMS_GPIO_PULL_UP_DOWN_PULLUP 2
-#define SMS_GPIO_PULL_UP_DOWN_KEEPER 3
- u8 PullUpDown;
-
-#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0
-#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1
- u8 InputCharacteristics;
-
-#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */
+ /* 10xx */
+#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0
+#define SMS_GPIO_OUTPUT_SLEW_WRATE_SLOW 1
+ /* 11xx */
+#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0
+#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1
+#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2
+#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3
-#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */
-#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */
- u8 OutputSlewRate;
+ u8 outputslewrate;
-#define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */
-#define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */
-#define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */
-#define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */
+ /* 10xx */
+#define SMS_GPIO_OUTPUTDRIVING_S_4mA 0
+#define SMS_GPIO_OUTPUTDRIVING_S_8mA 1
+#define SMS_GPIO_OUTPUTDRIVING_S_12mA 2
+#define SMS_GPIO_OUTPUTDRIVING_S_16mA 3
+
+ /* 11xx*/
+#define SMS_GPIO_OUTPUTDRIVING_1_5mA 0
+#define SMS_GPIO_OUTPUTDRIVING_2_8mA 1
+#define SMS_GPIO_OUTPUTDRIVING_4mA 2
+#define SMS_GPIO_OUTPUTDRIVING_7mA 3
+#define SMS_GPIO_OUTPUTDRIVING_10mA 4
+#define SMS_GPIO_OUTPUTDRIVING_11mA 5
+#define SMS_GPIO_OUTPUTDRIVING_14mA 6
+#define SMS_GPIO_OUTPUTDRIVING_16mA 7
-#define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */
-#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */
- u8 OutputDriving;
+ u8 outputdriving;
};
-extern void smscore_registry_setmode(char *devpath, int mode);
+char *smscore_translate_msg(enum msg_types msgtype);
+
extern int smscore_registry_getmode(char *devpath);
extern int smscore_register_hotplug(hotplug_t hotplug);
@@ -721,8 +1139,6 @@ extern void smscore_onresponse(struct smscore_device_t *coredev,
extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
struct vm_area_struct *vma);
-extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
- int mode, char *filename);
extern int smscore_send_fw_file(struct smscore_device_t *coredev,
u8 *ufwbuf, int size);
@@ -737,11 +1153,11 @@ int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
/* new GPIO management */
-extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
- struct smscore_gpio_config *pGpioConfig);
-extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
- u8 NewLevel);
-extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
+extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 pin_num,
+ struct smscore_config_gpio *p_gpio_config);
+extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 pin_num,
+ u8 new_level);
+extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 pin_num,
u8 *level);
void smscore_set_board_id(struct smscore_device_t *core, int id);
@@ -760,7 +1176,8 @@ int smscore_led_state(struct smscore_device_t *core, int led);
#define dprintk(kern, lvl, fmt, arg...) do {\
if (sms_dbg & lvl) \
- sms_printk(kern, fmt, ##arg); } while (0)
+ sms_printk(kern, fmt, ##arg); \
+} while (0)
#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
#define sms_err(fmt, arg...) \
diff --git a/drivers/media/common/siano/smsdvb-debugfs.c b/drivers/media/common/siano/smsdvb-debugfs.c
new file mode 100644
index 00000000000..2408d7e9451
--- /dev/null
+++ b/drivers/media/common/siano/smsdvb-debugfs.c
@@ -0,0 +1,551 @@
+/***********************************************************************
+ *
+ * Copyright(c) 2013 Mauro Carvalho Chehab
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ ***********************************************************************/
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+
+#include "smscoreapi.h"
+
+#include "smsdvb.h"
+
+static struct dentry *smsdvb_debugfs_usb_root;
+
+struct smsdvb_debugfs {
+ struct kref refcount;
+ spinlock_t lock;
+
+ char stats_data[PAGE_SIZE];
+ unsigned stats_count;
+ bool stats_was_read;
+
+ wait_queue_head_t stats_queue;
+};
+
+static void smsdvb_print_dvb_stats(struct smsdvb_debugfs *debug_data,
+ struct sms_stats *p)
+{
+ int n = 0;
+ char *buf;
+
+ spin_lock(&debug_data->lock);
+ if (debug_data->stats_count) {
+ spin_unlock(&debug_data->lock);
+ return;
+ }
+
+ buf = debug_data->stats_data;
+
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "is_rf_locked = %d\n", p->is_rf_locked);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "is_demod_locked = %d\n", p->is_demod_locked);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "is_external_lna_on = %d\n", p->is_external_lna_on);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "SNR = %d\n", p->SNR);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "ber = %d\n", p->ber);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "FIB_CRC = %d\n", p->FIB_CRC);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "ts_per = %d\n", p->ts_per);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "MFER = %d\n", p->MFER);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "RSSI = %d\n", p->RSSI);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "in_band_pwr = %d\n", p->in_band_pwr);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "carrier_offset = %d\n", p->carrier_offset);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "modem_state = %d\n", p->modem_state);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "frequency = %d\n", p->frequency);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "bandwidth = %d\n", p->bandwidth);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "transmission_mode = %d\n", p->transmission_mode);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "modem_state = %d\n", p->modem_state);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "guard_interval = %d\n", p->guard_interval);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "code_rate = %d\n", p->code_rate);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "lp_code_rate = %d\n", p->lp_code_rate);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "hierarchy = %d\n", p->hierarchy);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "constellation = %d\n", p->constellation);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "burst_size = %d\n", p->burst_size);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "burst_duration = %d\n", p->burst_duration);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "burst_cycle_time = %d\n", p->burst_cycle_time);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "calc_burst_cycle_time = %d\n",
+ p->calc_burst_cycle_time);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "num_of_rows = %d\n", p->num_of_rows);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "num_of_padd_cols = %d\n", p->num_of_padd_cols);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "num_of_punct_cols = %d\n", p->num_of_punct_cols);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "error_ts_packets = %d\n", p->error_ts_packets);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "total_ts_packets = %d\n", p->total_ts_packets);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "num_of_valid_mpe_tlbs = %d\n", p->num_of_valid_mpe_tlbs);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "num_of_invalid_mpe_tlbs = %d\n", p->num_of_invalid_mpe_tlbs);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "num_of_corrected_mpe_tlbs = %d\n", p->num_of_corrected_mpe_tlbs);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "ber_error_count = %d\n", p->ber_error_count);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "ber_bit_count = %d\n", p->ber_bit_count);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "pre_ber = %d\n", p->pre_ber);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "cell_id = %d\n", p->cell_id);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "dvbh_srv_ind_hp = %d\n", p->dvbh_srv_ind_hp);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "dvbh_srv_ind_lp = %d\n", p->dvbh_srv_ind_lp);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "num_mpe_received = %d\n", p->num_mpe_received);
+
+ debug_data->stats_count = n;
+ spin_unlock(&debug_data->lock);
+ wake_up(&debug_data->stats_queue);
+}
+
+static void smsdvb_print_isdb_stats(struct smsdvb_debugfs *debug_data,
+ struct sms_isdbt_stats *p)
+{
+ int i, n = 0;
+ char *buf;
+
+ spin_lock(&debug_data->lock);
+ if (debug_data->stats_count) {
+ spin_unlock(&debug_data->lock);
+ return;
+ }
+
+ buf = debug_data->stats_data;
+
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "statistics_type = %d\t", p->statistics_type);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "full_size = %d\n", p->full_size);
+
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "is_rf_locked = %d\t\t", p->is_rf_locked);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "is_demod_locked = %d\t", p->is_demod_locked);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "is_external_lna_on = %d\n", p->is_external_lna_on);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "SNR = %d dB\t\t", p->SNR);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "RSSI = %d dBm\t\t", p->RSSI);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "in_band_pwr = %d dBm\n", p->in_band_pwr);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "carrier_offset = %d\t", p->carrier_offset);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "bandwidth = %d\t\t", p->bandwidth);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "frequency = %d Hz\n", p->frequency);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "transmission_mode = %d\t", p->transmission_mode);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "modem_state = %d\t\t", p->modem_state);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "guard_interval = %d\n", p->guard_interval);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "system_type = %d\t\t", p->system_type);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "partial_reception = %d\t", p->partial_reception);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "num_of_layers = %d\n", p->num_of_layers);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
+
+ for (i = 0; i < 3; i++) {
+ if (p->layer_info[i].number_of_segments < 1 ||
+ p->layer_info[i].number_of_segments > 13)
+ continue;
+
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
+ p->layer_info[i].code_rate);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
+ p->layer_info[i].constellation);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
+ p->layer_info[i].ber);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",
+ p->layer_info[i].ber_error_count);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
+ p->layer_info[i].ber_bit_count);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
+ p->layer_info[i].pre_ber);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
+ p->layer_info[i].ts_per);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",
+ p->layer_info[i].error_ts_packets);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",
+ p->layer_info[i].total_ts_packets);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
+ p->layer_info[i].ti_ldepth_i);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "\tnumber_of_segments = %d\t",
+ p->layer_info[i].number_of_segments);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
+ p->layer_info[i].tmcc_errors);
+ }
+
+ debug_data->stats_count = n;
+ spin_unlock(&debug_data->lock);
+ wake_up(&debug_data->stats_queue);
+}
+
+static void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data,
+ struct sms_isdbt_stats_ex *p)
+{
+ int i, n = 0;
+ char *buf;
+
+ spin_lock(&debug_data->lock);
+ if (debug_data->stats_count) {
+ spin_unlock(&debug_data->lock);
+ return;
+ }
+
+ buf = debug_data->stats_data;
+
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "statistics_type = %d\t", p->statistics_type);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "full_size = %d\n", p->full_size);
+
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "is_rf_locked = %d\t\t", p->is_rf_locked);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "is_demod_locked = %d\t", p->is_demod_locked);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "is_external_lna_on = %d\n", p->is_external_lna_on);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "SNR = %d dB\t\t", p->SNR);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "RSSI = %d dBm\t\t", p->RSSI);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "in_band_pwr = %d dBm\n", p->in_band_pwr);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "carrier_offset = %d\t", p->carrier_offset);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "bandwidth = %d\t\t", p->bandwidth);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "frequency = %d Hz\n", p->frequency);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "transmission_mode = %d\t", p->transmission_mode);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "modem_state = %d\t\t", p->modem_state);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "guard_interval = %d\n", p->guard_interval);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "system_type = %d\t\t", p->system_type);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "partial_reception = %d\t", p->partial_reception);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "num_of_layers = %d\n", p->num_of_layers);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "segment_number = %d\t",
+ p->segment_number);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "tune_bw = %d\n",
+ p->tune_bw);
+
+ for (i = 0; i < 3; i++) {
+ if (p->layer_info[i].number_of_segments < 1 ||
+ p->layer_info[i].number_of_segments > 13)
+ continue;
+
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
+ p->layer_info[i].code_rate);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
+ p->layer_info[i].constellation);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
+ p->layer_info[i].ber);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",
+ p->layer_info[i].ber_error_count);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
+ p->layer_info[i].ber_bit_count);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
+ p->layer_info[i].pre_ber);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
+ p->layer_info[i].ts_per);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",
+ p->layer_info[i].error_ts_packets);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",
+ p->layer_info[i].total_ts_packets);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
+ p->layer_info[i].ti_ldepth_i);
+ n += snprintf(&buf[n], PAGE_SIZE - n,
+ "\tnumber_of_segments = %d\t",
+ p->layer_info[i].number_of_segments);
+ n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
+ p->layer_info[i].tmcc_errors);
+ }
+
+
+ debug_data->stats_count = n;
+ spin_unlock(&debug_data->lock);
+
+ wake_up(&debug_data->stats_queue);
+}
+
+static int smsdvb_stats_open(struct inode *inode, struct file *file)
+{
+ struct smsdvb_client_t *client = inode->i_private;
+ struct smsdvb_debugfs *debug_data = client->debug_data;
+
+ kref_get(&debug_data->refcount);
+
+ spin_lock(&debug_data->lock);
+ debug_data->stats_count = 0;
+ debug_data->stats_was_read = false;
+ spin_unlock(&debug_data->lock);
+
+ file->private_data = debug_data;
+
+ return 0;
+}
+
+static void smsdvb_debugfs_data_release(struct kref *ref)
+{
+ struct smsdvb_debugfs *debug_data;
+
+ debug_data = container_of(ref, struct smsdvb_debugfs, refcount);
+ kfree(debug_data);
+}
+
+static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data)
+{
+ int rc = 1;
+
+ spin_lock(&debug_data->lock);
+
+ if (debug_data->stats_was_read)
+ goto exit;
+
+ rc = debug_data->stats_count;
+
+exit:
+ spin_unlock(&debug_data->lock);
+ return rc;
+}
+
+static unsigned int smsdvb_stats_poll(struct file *file, poll_table *wait)
+{
+ struct smsdvb_debugfs *debug_data = file->private_data;
+ int rc;
+
+ kref_get(&debug_data->refcount);
+
+ poll_wait(file, &debug_data->stats_queue, wait);
+
+ rc = smsdvb_stats_wait_read(debug_data);
+ if (rc > 0)
+ rc = POLLIN | POLLRDNORM;
+
+ kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
+
+ return rc;
+}
+
+static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf,
+ size_t nbytes, loff_t *ppos)
+{
+ int rc = 0, len;
+ struct smsdvb_debugfs *debug_data = file->private_data;
+
+ kref_get(&debug_data->refcount);
+
+ if (file->f_flags & O_NONBLOCK) {
+ rc = smsdvb_stats_wait_read(debug_data);
+ if (!rc) {
+ rc = -EWOULDBLOCK;
+ goto ret;
+ }
+ } else {
+ rc = wait_event_interruptible(debug_data->stats_queue,
+ smsdvb_stats_wait_read(debug_data));
+ if (rc < 0)
+ goto ret;
+ }
+
+ if (debug_data->stats_was_read) {
+ rc = 0; /* EOF */
+ goto ret;
+ }
+
+ len = debug_data->stats_count - *ppos;
+ if (len >= 0)
+ rc = simple_read_from_buffer(user_buf, nbytes, ppos,
+ debug_data->stats_data, len);
+ else
+ rc = 0;
+
+ if (*ppos >= debug_data->stats_count) {
+ spin_lock(&debug_data->lock);
+ debug_data->stats_was_read = true;
+ spin_unlock(&debug_data->lock);
+ }
+ret:
+ kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
+ return rc;
+}
+
+static int smsdvb_stats_release(struct inode *inode, struct file *file)
+{
+ struct smsdvb_debugfs *debug_data = file->private_data;
+
+ spin_lock(&debug_data->lock);
+ debug_data->stats_was_read = true; /* return EOF to read() */
+ spin_unlock(&debug_data->lock);
+ wake_up_interruptible_sync(&debug_data->stats_queue);
+
+ kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
+ file->private_data = NULL;
+
+ return 0;
+}
+
+static const struct file_operations debugfs_stats_ops = {
+ .open = smsdvb_stats_open,
+ .poll = smsdvb_stats_poll,
+ .read = smsdvb_stats_read,
+ .release = smsdvb_stats_release,
+ .llseek = generic_file_llseek,
+};
+
+/*
+ * Functions used by smsdvb, in order to create the interfaces
+ */
+
+int smsdvb_debugfs_create(struct smsdvb_client_t *client)
+{
+ struct smscore_device_t *coredev = client->coredev;
+ struct dentry *d;
+ struct smsdvb_debugfs *debug_data;
+
+ if (!smsdvb_debugfs_usb_root || !coredev->is_usb_device)
+ return -ENODEV;
+
+ client->debugfs = debugfs_create_dir(coredev->devpath,
+ smsdvb_debugfs_usb_root);
+ if (IS_ERR_OR_NULL(client->debugfs)) {
+ pr_info("Unable to create debugfs %s directory.\n",
+ coredev->devpath);
+ return -ENODEV;
+ }
+
+ d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs,
+ client, &debugfs_stats_ops);
+ if (!d) {
+ debugfs_remove(client->debugfs);
+ return -ENOMEM;
+ }
+
+ debug_data = kzalloc(sizeof(*client->debug_data), GFP_KERNEL);
+ if (!debug_data)
+ return -ENOMEM;
+
+ client->debug_data = debug_data;
+ client->prt_dvb_stats = smsdvb_print_dvb_stats;
+ client->prt_isdb_stats = smsdvb_print_isdb_stats;
+ client->prt_isdb_stats_ex = smsdvb_print_isdb_stats_ex;
+
+ init_waitqueue_head(&debug_data->stats_queue);
+ spin_lock_init(&debug_data->lock);
+ kref_init(&debug_data->refcount);
+
+ return 0;
+}
+
+void smsdvb_debugfs_release(struct smsdvb_client_t *client)
+{
+ if (!client->debugfs)
+ return;
+
+ client->prt_dvb_stats = NULL;
+ client->prt_isdb_stats = NULL;
+ client->prt_isdb_stats_ex = NULL;
+
+ debugfs_remove_recursive(client->debugfs);
+ kref_put(&client->debug_data->refcount, smsdvb_debugfs_data_release);
+
+ client->debug_data = NULL;
+ client->debugfs = NULL;
+}
+
+int smsdvb_debugfs_register(void)
+{
+ struct dentry *d;
+
+ /*
+ * FIXME: This was written to debug Siano USB devices. So, it creates
+ * the debugfs node under <debugfs>/usb.
+ * A similar logic would be needed for Siano sdio devices, but, in that
+ * case, usb_debug_root is not a good choice.
+ *
+ * Perhaps the right fix here would be to create another sysfs root
+ * node for sdio-based boards, but this may need some logic at sdio
+ * subsystem.
+ */
+ d = debugfs_create_dir("smsdvb", usb_debug_root);
+ if (IS_ERR_OR_NULL(d)) {
+ sms_err("Couldn't create sysfs node for smsdvb");
+ return PTR_ERR(d);
+ } else {
+ smsdvb_debugfs_usb_root = d;
+ }
+ return 0;
+}
+
+void smsdvb_debugfs_unregister(void)
+{
+ debugfs_remove_recursive(smsdvb_debugfs_usb_root);
+ smsdvb_debugfs_usb_root = NULL;
+}
diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c
new file mode 100644
index 00000000000..85151efdd94
--- /dev/null
+++ b/drivers/media/common/siano/smsdvb-main.c
@@ -0,0 +1,1232 @@
+/****************************************************************
+
+Siano Mobile Silicon, Inc.
+MDTV receiver kernel modules.
+Copyright (C) 2006-2008, Uri Shkolnik
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+ 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, see <http://www.gnu.org/licenses/>.
+
+****************************************************************/
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <asm/div64.h>
+
+#include "dmxdev.h"
+#include "dvbdev.h"
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+
+#include "smsdvb.h"
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static struct list_head g_smsdvb_clients;
+static struct mutex g_smsdvb_clientslock;
+
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
+
+static u32 sms_to_guard_interval_table[] = {
+ [0] = GUARD_INTERVAL_1_32,
+ [1] = GUARD_INTERVAL_1_16,
+ [2] = GUARD_INTERVAL_1_8,
+ [3] = GUARD_INTERVAL_1_4,
+};
+
+static u32 sms_to_code_rate_table[] = {
+ [0] = FEC_1_2,
+ [1] = FEC_2_3,
+ [2] = FEC_3_4,
+ [3] = FEC_5_6,
+ [4] = FEC_7_8,
+};
+
+
+static u32 sms_to_hierarchy_table[] = {
+ [0] = HIERARCHY_NONE,
+ [1] = HIERARCHY_1,
+ [2] = HIERARCHY_2,
+ [3] = HIERARCHY_4,
+};
+
+static u32 sms_to_modulation_table[] = {
+ [0] = QPSK,
+ [1] = QAM_16,
+ [2] = QAM_64,
+ [3] = DQPSK,
+};
+
+
+/* Events that may come from DVB v3 adapter */
+static void sms_board_dvb3_event(struct smsdvb_client_t *client,
+ enum SMS_DVB3_EVENTS event) {
+
+ struct smscore_device_t *coredev = client->coredev;
+ switch (event) {
+ case DVB3_EVENT_INIT:
+ sms_debug("DVB3_EVENT_INIT");
+ sms_board_event(coredev, BOARD_EVENT_BIND);
+ break;
+ case DVB3_EVENT_SLEEP:
+ sms_debug("DVB3_EVENT_SLEEP");
+ sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
+ break;
+ case DVB3_EVENT_HOTPLUG:
+ sms_debug("DVB3_EVENT_HOTPLUG");
+ sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
+ break;
+ case DVB3_EVENT_FE_LOCK:
+ if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
+ client->event_fe_state = DVB3_EVENT_FE_LOCK;
+ sms_debug("DVB3_EVENT_FE_LOCK");
+ sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
+ }
+ break;
+ case DVB3_EVENT_FE_UNLOCK:
+ if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
+ client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
+ sms_debug("DVB3_EVENT_FE_UNLOCK");
+ sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
+ }
+ break;
+ case DVB3_EVENT_UNC_OK:
+ if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
+ client->event_unc_state = DVB3_EVENT_UNC_OK;
+ sms_debug("DVB3_EVENT_UNC_OK");
+ sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
+ }
+ break;
+ case DVB3_EVENT_UNC_ERR:
+ if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
+ client->event_unc_state = DVB3_EVENT_UNC_ERR;
+ sms_debug("DVB3_EVENT_UNC_ERR");
+ sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
+ }
+ break;
+
+ default:
+ sms_err("Unknown dvb3 api event");
+ break;
+ }
+}
+
+static void smsdvb_stats_not_ready(struct dvb_frontend *fe)
+{
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+ struct smscore_device_t *coredev = client->coredev;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int i, n_layers;
+
+ switch (smscore_get_device_mode(coredev)) {
+ case DEVICE_MODE_ISDBT:
+ case DEVICE_MODE_ISDBT_BDA:
+ n_layers = 4;
+ break;
+ default:
+ n_layers = 1;
+ }
+
+ /* Global stats */
+ c->strength.len = 1;
+ c->cnr.len = 1;
+ c->strength.stat[0].scale = FE_SCALE_DECIBEL;
+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+
+ /* Per-layer stats */
+ c->post_bit_error.len = n_layers;
+ c->post_bit_count.len = n_layers;
+ c->block_error.len = n_layers;
+ c->block_count.len = n_layers;
+
+ /*
+ * Put all of them at FE_SCALE_NOT_AVAILABLE. They're dynamically
+ * changed when the stats become available.
+ */
+ for (i = 0; i < n_layers; i++) {
+ c->post_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+ c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+ c->block_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
+ }
+}
+
+static inline int sms_to_mode(u32 mode)
+{
+ switch (mode) {
+ case 2:
+ return TRANSMISSION_MODE_2K;
+ case 4:
+ return TRANSMISSION_MODE_4K;
+ case 8:
+ return TRANSMISSION_MODE_8K;
+ }
+ return TRANSMISSION_MODE_AUTO;
+}
+
+static inline int sms_to_status(u32 is_demod_locked, u32 is_rf_locked)
+{
+ if (is_demod_locked)
+ return FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
+ FE_HAS_SYNC | FE_HAS_LOCK;
+
+ if (is_rf_locked)
+ return FE_HAS_SIGNAL | FE_HAS_CARRIER;
+
+ return 0;
+}
+
+static inline u32 sms_to_bw(u32 value)
+{
+ return value * 1000000;
+}
+
+#define convert_from_table(value, table, defval) ({ \
+ u32 __ret; \
+ if (value < ARRAY_SIZE(table)) \
+ __ret = table[value]; \
+ else \
+ __ret = defval; \
+ __ret; \
+})
+
+#define sms_to_guard_interval(value) \
+ convert_from_table(value, sms_to_guard_interval_table, \
+ GUARD_INTERVAL_AUTO);
+
+#define sms_to_code_rate(value) \
+ convert_from_table(value, sms_to_code_rate_table, \
+ FEC_NONE);
+
+#define sms_to_hierarchy(value) \
+ convert_from_table(value, sms_to_hierarchy_table, \
+ FEC_NONE);
+
+#define sms_to_modulation(value) \
+ convert_from_table(value, sms_to_modulation_table, \
+ FEC_NONE);
+
+static void smsdvb_update_tx_params(struct smsdvb_client_t *client,
+ struct sms_tx_stats *p)
+{
+ struct dvb_frontend *fe = &client->frontend;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ c->frequency = p->frequency;
+ client->fe_status = sms_to_status(p->is_demod_locked, 0);
+ c->bandwidth_hz = sms_to_bw(p->bandwidth);
+ c->transmission_mode = sms_to_mode(p->transmission_mode);
+ c->guard_interval = sms_to_guard_interval(p->guard_interval);
+ c->code_rate_HP = sms_to_code_rate(p->code_rate);
+ c->code_rate_LP = sms_to_code_rate(p->lp_code_rate);
+ c->hierarchy = sms_to_hierarchy(p->hierarchy);
+ c->modulation = sms_to_modulation(p->constellation);
+}
+
+static void smsdvb_update_per_slices(struct smsdvb_client_t *client,
+ struct RECEPTION_STATISTICS_PER_SLICES_S *p)
+{
+ struct dvb_frontend *fe = &client->frontend;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u64 tmp;
+
+ client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked);
+ c->modulation = sms_to_modulation(p->constellation);
+
+ /* signal Strength, in DBm */
+ c->strength.stat[0].uvalue = p->in_band_power * 1000;
+
+ /* Carrier to noise ratio, in DB */
+ c->cnr.stat[0].svalue = p->snr * 1000;
+
+ /* PER/BER requires demod lock */
+ if (!p->is_demod_locked)
+ return;
+
+ /* TS PER */
+ client->last_per = c->block_error.stat[0].uvalue;
+ c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_error.stat[0].uvalue += p->ets_packets;
+ c->block_count.stat[0].uvalue += p->ets_packets + p->ts_packets;
+
+ /* ber */
+ c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[0].uvalue += p->ber_error_count;
+ c->post_bit_count.stat[0].uvalue += p->ber_bit_count;
+
+ /* Legacy PER/BER */
+ tmp = p->ets_packets * 65535;
+ if (p->ts_packets + p->ets_packets)
+ do_div(tmp, p->ts_packets + p->ets_packets);
+ client->legacy_per = tmp;
+}
+
+static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client,
+ struct sms_stats *p)
+{
+ struct dvb_frontend *fe = &client->frontend;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ if (client->prt_dvb_stats)
+ client->prt_dvb_stats(client->debug_data, p);
+
+ client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked);
+
+ /* Update DVB modulation parameters */
+ c->frequency = p->frequency;
+ client->fe_status = sms_to_status(p->is_demod_locked, 0);
+ c->bandwidth_hz = sms_to_bw(p->bandwidth);
+ c->transmission_mode = sms_to_mode(p->transmission_mode);
+ c->guard_interval = sms_to_guard_interval(p->guard_interval);
+ c->code_rate_HP = sms_to_code_rate(p->code_rate);
+ c->code_rate_LP = sms_to_code_rate(p->lp_code_rate);
+ c->hierarchy = sms_to_hierarchy(p->hierarchy);
+ c->modulation = sms_to_modulation(p->constellation);
+
+ /* update reception data */
+ c->lna = p->is_external_lna_on ? 1 : 0;
+
+ /* Carrier to noise ratio, in DB */
+ c->cnr.stat[0].svalue = p->SNR * 1000;
+
+ /* signal Strength, in DBm */
+ c->strength.stat[0].uvalue = p->in_band_pwr * 1000;
+
+ /* PER/BER requires demod lock */
+ if (!p->is_demod_locked)
+ return;
+
+ /* TS PER */
+ client->last_per = c->block_error.stat[0].uvalue;
+ c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_error.stat[0].uvalue += p->error_ts_packets;
+ c->block_count.stat[0].uvalue += p->total_ts_packets;
+
+ /* ber */
+ c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[0].uvalue += p->ber_error_count;
+ c->post_bit_count.stat[0].uvalue += p->ber_bit_count;
+
+ /* Legacy PER/BER */
+ client->legacy_ber = p->ber;
+};
+
+static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client,
+ struct sms_isdbt_stats *p)
+{
+ struct dvb_frontend *fe = &client->frontend;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct sms_isdbt_layer_stats *lr;
+ int i, n_layers;
+
+ if (client->prt_isdb_stats)
+ client->prt_isdb_stats(client->debug_data, p);
+
+ client->fe_status = sms_to_status(p->is_demod_locked, p->is_rf_locked);
+
+ /*
+ * Firmware 2.1 seems to report only lock status and
+ * signal strength. The signal strength indicator is at the
+ * wrong field.
+ */
+ if (p->statistics_type == 0) {
+ c->strength.stat[0].uvalue = ((s32)p->transmission_mode) * 1000;
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ return;
+ }
+
+ /* Update ISDB-T transmission parameters */
+ c->frequency = p->frequency;
+ c->bandwidth_hz = sms_to_bw(p->bandwidth);
+ c->transmission_mode = sms_to_mode(p->transmission_mode);
+ c->guard_interval = sms_to_guard_interval(p->guard_interval);
+ c->isdbt_partial_reception = p->partial_reception ? 1 : 0;
+ n_layers = p->num_of_layers;
+ if (n_layers < 1)
+ n_layers = 1;
+ if (n_layers > 3)
+ n_layers = 3;
+ c->isdbt_layer_enabled = 0;
+
+ /* update reception data */
+ c->lna = p->is_external_lna_on ? 1 : 0;
+
+ /* Carrier to noise ratio, in DB */
+ c->cnr.stat[0].svalue = p->SNR * 1000;
+
+ /* signal Strength, in DBm */
+ c->strength.stat[0].uvalue = p->in_band_pwr * 1000;
+
+ /* PER/BER and per-layer stats require demod lock */
+ if (!p->is_demod_locked)
+ return;
+
+ client->last_per = c->block_error.stat[0].uvalue;
+
+ /* Clears global counters, as the code below will sum it again */
+ c->block_error.stat[0].uvalue = 0;
+ c->block_count.stat[0].uvalue = 0;
+ c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[0].uvalue = 0;
+ c->post_bit_count.stat[0].uvalue = 0;
+ c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+
+ for (i = 0; i < n_layers; i++) {
+ lr = &p->layer_info[i];
+
+ /* Update per-layer transmission parameters */
+ if (lr->number_of_segments > 0 && lr->number_of_segments < 13) {
+ c->isdbt_layer_enabled |= 1 << i;
+ c->layer[i].segment_count = lr->number_of_segments;
+ } else {
+ continue;
+ }
+ c->layer[i].modulation = sms_to_modulation(lr->constellation);
+
+ /* TS PER */
+ c->block_error.stat[i + 1].scale = FE_SCALE_COUNTER;
+ c->block_count.stat[i + 1].scale = FE_SCALE_COUNTER;
+ c->block_error.stat[i + 1].uvalue += lr->error_ts_packets;
+ c->block_count.stat[i + 1].uvalue += lr->total_ts_packets;
+
+ /* Update global PER counter */
+ c->block_error.stat[0].uvalue += lr->error_ts_packets;
+ c->block_count.stat[0].uvalue += lr->total_ts_packets;
+
+ /* BER */
+ c->post_bit_error.stat[i + 1].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[i + 1].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[i + 1].uvalue += lr->ber_error_count;
+ c->post_bit_count.stat[i + 1].uvalue += lr->ber_bit_count;
+
+ /* Update global BER counter */
+ c->post_bit_error.stat[0].uvalue += lr->ber_error_count;
+ c->post_bit_count.stat[0].uvalue += lr->ber_bit_count;
+ }
+}
+
+static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client,
+ struct sms_isdbt_stats_ex *p)
+{
+ struct dvb_frontend *fe = &client->frontend;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct sms_isdbt_layer_stats *lr;
+ int i, n_layers;
+
+ if (client->prt_isdb_stats_ex)
+ client->prt_isdb_stats_ex(client->debug_data, p);
+
+ /* Update ISDB-T transmission parameters */
+ c->frequency = p->frequency;
+ client->fe_status = sms_to_status(p->is_demod_locked, 0);
+ c->bandwidth_hz = sms_to_bw(p->bandwidth);
+ c->transmission_mode = sms_to_mode(p->transmission_mode);
+ c->guard_interval = sms_to_guard_interval(p->guard_interval);
+ c->isdbt_partial_reception = p->partial_reception ? 1 : 0;
+ n_layers = p->num_of_layers;
+ if (n_layers < 1)
+ n_layers = 1;
+ if (n_layers > 3)
+ n_layers = 3;
+ c->isdbt_layer_enabled = 0;
+
+ /* update reception data */
+ c->lna = p->is_external_lna_on ? 1 : 0;
+
+ /* Carrier to noise ratio, in DB */
+ c->cnr.stat[0].svalue = p->SNR * 1000;
+
+ /* signal Strength, in DBm */
+ c->strength.stat[0].uvalue = p->in_band_pwr * 1000;
+
+ /* PER/BER and per-layer stats require demod lock */
+ if (!p->is_demod_locked)
+ return;
+
+ client->last_per = c->block_error.stat[0].uvalue;
+
+ /* Clears global counters, as the code below will sum it again */
+ c->block_error.stat[0].uvalue = 0;
+ c->block_count.stat[0].uvalue = 0;
+ c->block_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->block_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[0].uvalue = 0;
+ c->post_bit_count.stat[0].uvalue = 0;
+ c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+
+ c->post_bit_error.len = n_layers + 1;
+ c->post_bit_count.len = n_layers + 1;
+ c->block_error.len = n_layers + 1;
+ c->block_count.len = n_layers + 1;
+ for (i = 0; i < n_layers; i++) {
+ lr = &p->layer_info[i];
+
+ /* Update per-layer transmission parameters */
+ if (lr->number_of_segments > 0 && lr->number_of_segments < 13) {
+ c->isdbt_layer_enabled |= 1 << i;
+ c->layer[i].segment_count = lr->number_of_segments;
+ } else {
+ continue;
+ }
+ c->layer[i].modulation = sms_to_modulation(lr->constellation);
+
+ /* TS PER */
+ c->block_error.stat[i + 1].scale = FE_SCALE_COUNTER;
+ c->block_count.stat[i + 1].scale = FE_SCALE_COUNTER;
+ c->block_error.stat[i + 1].uvalue += lr->error_ts_packets;
+ c->block_count.stat[i + 1].uvalue += lr->total_ts_packets;
+
+ /* Update global PER counter */
+ c->block_error.stat[0].uvalue += lr->error_ts_packets;
+ c->block_count.stat[0].uvalue += lr->total_ts_packets;
+
+ /* ber */
+ c->post_bit_error.stat[i + 1].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[i + 1].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[i + 1].uvalue += lr->ber_error_count;
+ c->post_bit_count.stat[i + 1].uvalue += lr->ber_bit_count;
+
+ /* Update global ber counter */
+ c->post_bit_error.stat[0].uvalue += lr->ber_error_count;
+ c->post_bit_count.stat[0].uvalue += lr->ber_bit_count;
+ }
+}
+
+static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
+{
+ struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
+ struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) (((u8 *) cb->p)
+ + cb->offset);
+ void *p = phdr + 1;
+ struct dvb_frontend *fe = &client->frontend;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ bool is_status_update = false;
+
+ switch (phdr->msg_type) {
+ case MSG_SMS_DVBT_BDA_DATA:
+ /*
+ * Only feed data to dvb demux if are there any feed listening
+ * to it and if the device has tuned
+ */
+ if (client->feed_users && client->has_tuned)
+ dvb_dmx_swfilter(&client->demux, p,
+ cb->size - sizeof(struct sms_msg_hdr));
+ break;
+
+ case MSG_SMS_RF_TUNE_RES:
+ case MSG_SMS_ISDBT_TUNE_RES:
+ complete(&client->tune_done);
+ break;
+
+ case MSG_SMS_SIGNAL_DETECTED_IND:
+ client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
+ FE_HAS_VITERBI | FE_HAS_SYNC |
+ FE_HAS_LOCK;
+
+ is_status_update = true;
+ break;
+
+ case MSG_SMS_NO_SIGNAL_IND:
+ client->fe_status = 0;
+
+ is_status_update = true;
+ break;
+
+ case MSG_SMS_TRANSMISSION_IND:
+ smsdvb_update_tx_params(client, p);
+
+ is_status_update = true;
+ break;
+
+ case MSG_SMS_HO_PER_SLICES_IND:
+ smsdvb_update_per_slices(client, p);
+
+ is_status_update = true;
+ break;
+
+ case MSG_SMS_GET_STATISTICS_RES:
+ switch (smscore_get_device_mode(client->coredev)) {
+ case DEVICE_MODE_ISDBT:
+ case DEVICE_MODE_ISDBT_BDA:
+ smsdvb_update_isdbt_stats(client, p);
+ break;
+ default:
+ /* Skip sms_msg_statistics_info:request_result field */
+ smsdvb_update_dvb_stats(client, p + sizeof(u32));
+ }
+
+ is_status_update = true;
+ break;
+
+ /* Only for ISDB-T */
+ case MSG_SMS_GET_STATISTICS_EX_RES:
+ /* Skip sms_msg_statistics_info:request_result field? */
+ smsdvb_update_isdbt_stats_ex(client, p + sizeof(u32));
+ is_status_update = true;
+ break;
+ default:
+ sms_info("message not handled");
+ }
+ smscore_putbuffer(client->coredev, cb);
+
+ if (is_status_update) {
+ if (client->fe_status & FE_HAS_LOCK) {
+ sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
+ if (client->last_per == c->block_error.stat[0].uvalue)
+ sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
+ else
+ sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR);
+ client->has_tuned = true;
+ } else {
+ smsdvb_stats_not_ready(fe);
+ client->has_tuned = false;
+ sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
+ }
+ complete(&client->stats_done);
+ }
+
+ return 0;
+}
+
+static void smsdvb_unregister_client(struct smsdvb_client_t *client)
+{
+ /* must be called under clientslock */
+
+ list_del(&client->entry);
+
+ smsdvb_debugfs_release(client);
+ smscore_unregister_client(client->smsclient);
+ dvb_unregister_frontend(&client->frontend);
+ dvb_dmxdev_release(&client->dmxdev);
+ dvb_dmx_release(&client->demux);
+ dvb_unregister_adapter(&client->adapter);
+ kfree(client);
+}
+
+static void smsdvb_onremove(void *context)
+{
+ kmutex_lock(&g_smsdvb_clientslock);
+
+ smsdvb_unregister_client((struct smsdvb_client_t *) context);
+
+ kmutex_unlock(&g_smsdvb_clientslock);
+}
+
+static int smsdvb_start_feed(struct dvb_demux_feed *feed)
+{
+ struct smsdvb_client_t *client =
+ container_of(feed->demux, struct smsdvb_client_t, demux);
+ struct sms_msg_data pid_msg;
+
+ sms_debug("add pid %d(%x)",
+ feed->pid, feed->pid);
+
+ client->feed_users++;
+
+ pid_msg.x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
+ pid_msg.x_msg_header.msg_dst_id = HIF_TASK;
+ pid_msg.x_msg_header.msg_flags = 0;
+ pid_msg.x_msg_header.msg_type = MSG_SMS_ADD_PID_FILTER_REQ;
+ pid_msg.x_msg_header.msg_length = sizeof(pid_msg);
+ pid_msg.msg_data[0] = feed->pid;
+
+ return smsclient_sendrequest(client->smsclient,
+ &pid_msg, sizeof(pid_msg));
+}
+
+static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
+{
+ struct smsdvb_client_t *client =
+ container_of(feed->demux, struct smsdvb_client_t, demux);
+ struct sms_msg_data pid_msg;
+
+ sms_debug("remove pid %d(%x)",
+ feed->pid, feed->pid);
+
+ client->feed_users--;
+
+ pid_msg.x_msg_header.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
+ pid_msg.x_msg_header.msg_dst_id = HIF_TASK;
+ pid_msg.x_msg_header.msg_flags = 0;
+ pid_msg.x_msg_header.msg_type = MSG_SMS_REMOVE_PID_FILTER_REQ;
+ pid_msg.x_msg_header.msg_length = sizeof(pid_msg);
+ pid_msg.msg_data[0] = feed->pid;
+
+ return smsclient_sendrequest(client->smsclient,
+ &pid_msg, sizeof(pid_msg));
+}
+
+static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
+ void *buffer, size_t size,
+ struct completion *completion)
+{
+ int rc;
+
+ rc = smsclient_sendrequest(client->smsclient, buffer, size);
+ if (rc < 0)
+ return rc;
+
+ return wait_for_completion_timeout(completion,
+ msecs_to_jiffies(2000)) ?
+ 0 : -ETIME;
+}
+
+static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
+{
+ int rc;
+ struct sms_msg_hdr msg;
+
+ /* Don't request stats too fast */
+ if (client->get_stats_jiffies &&
+ (!time_after(jiffies, client->get_stats_jiffies)))
+ return 0;
+ client->get_stats_jiffies = jiffies + msecs_to_jiffies(100);
+
+ msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
+ msg.msg_dst_id = HIF_TASK;
+ msg.msg_flags = 0;
+ msg.msg_length = sizeof(msg);
+
+ switch (smscore_get_device_mode(client->coredev)) {
+ case DEVICE_MODE_ISDBT:
+ case DEVICE_MODE_ISDBT_BDA:
+ /*
+ * Check for firmware version, to avoid breaking for old cards
+ */
+ if (client->coredev->fw_version >= 0x800)
+ msg.msg_type = MSG_SMS_GET_STATISTICS_EX_REQ;
+ else
+ msg.msg_type = MSG_SMS_GET_STATISTICS_REQ;
+ break;
+ default:
+ msg.msg_type = MSG_SMS_GET_STATISTICS_REQ;
+ }
+
+ rc = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg),
+ &client->stats_done);
+
+ return rc;
+}
+
+static inline int led_feedback(struct smsdvb_client_t *client)
+{
+ if (!(client->fe_status & FE_HAS_LOCK))
+ return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
+
+ return sms_board_led_feedback(client->coredev,
+ (client->legacy_ber == 0) ?
+ SMS_LED_HI : SMS_LED_LO);
+}
+
+static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
+{
+ int rc;
+ struct smsdvb_client_t *client;
+ client = container_of(fe, struct smsdvb_client_t, frontend);
+
+ rc = smsdvb_send_statistics_request(client);
+
+ *stat = client->fe_status;
+
+ led_feedback(client);
+
+ return rc;
+}
+
+static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ int rc;
+ struct smsdvb_client_t *client;
+
+ client = container_of(fe, struct smsdvb_client_t, frontend);
+
+ rc = smsdvb_send_statistics_request(client);
+
+ *ber = client->legacy_ber;
+
+ led_feedback(client);
+
+ return rc;
+}
+
+static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int rc;
+ s32 power = (s32) c->strength.stat[0].uvalue;
+ struct smsdvb_client_t *client;
+
+ client = container_of(fe, struct smsdvb_client_t, frontend);
+
+ rc = smsdvb_send_statistics_request(client);
+
+ if (power < -95)
+ *strength = 0;
+ else if (power > -29)
+ *strength = 65535;
+ else
+ *strength = (power + 95) * 65535 / 66;
+
+ led_feedback(client);
+
+ return rc;
+}
+
+static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int rc;
+ struct smsdvb_client_t *client;
+
+ client = container_of(fe, struct smsdvb_client_t, frontend);
+
+ rc = smsdvb_send_statistics_request(client);
+
+ /* Preferred scale for SNR with legacy API: 0.1 dB */
+ *snr = ((u32)c->cnr.stat[0].svalue) / 100;
+
+ led_feedback(client);
+
+ return rc;
+}
+
+static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ int rc;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct smsdvb_client_t *client;
+
+ client = container_of(fe, struct smsdvb_client_t, frontend);
+
+ rc = smsdvb_send_statistics_request(client);
+
+ *ucblocks = c->block_error.stat[0].uvalue;
+
+ led_feedback(client);
+
+ return rc;
+}
+
+static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *tune)
+{
+ sms_debug("");
+
+ tune->min_delay_ms = 400;
+ tune->step_size = 250000;
+ tune->max_drift = 0;
+ return 0;
+}
+
+static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+
+ struct {
+ struct sms_msg_hdr msg;
+ u32 Data[3];
+ } msg;
+
+ int ret;
+
+ client->fe_status = 0;
+ client->event_fe_state = -1;
+ client->event_unc_state = -1;
+ fe->dtv_property_cache.delivery_system = SYS_DVBT;
+
+ msg.msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
+ msg.msg.msg_dst_id = HIF_TASK;
+ msg.msg.msg_flags = 0;
+ msg.msg.msg_type = MSG_SMS_RF_TUNE_REQ;
+ msg.msg.msg_length = sizeof(msg);
+ msg.Data[0] = c->frequency;
+ msg.Data[2] = 12000000;
+
+ sms_info("%s: freq %d band %d", __func__, c->frequency,
+ c->bandwidth_hz);
+
+ switch (c->bandwidth_hz / 1000000) {
+ case 8:
+ msg.Data[1] = BW_8_MHZ;
+ break;
+ case 7:
+ msg.Data[1] = BW_7_MHZ;
+ break;
+ case 6:
+ msg.Data[1] = BW_6_MHZ;
+ break;
+ case 0:
+ return -EOPNOTSUPP;
+ default:
+ return -EINVAL;
+ }
+ /* Disable LNA, if any. An error is returned if no LNA is present */
+ ret = sms_board_lna_control(client->coredev, 0);
+ if (ret == 0) {
+ fe_status_t status;
+
+ /* tune with LNA off at first */
+ ret = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg),
+ &client->tune_done);
+
+ smsdvb_read_status(fe, &status);
+
+ if (status & FE_HAS_LOCK)
+ return ret;
+
+ /* previous tune didn't lock - enable LNA and tune again */
+ sms_board_lna_control(client->coredev, 1);
+ }
+
+ return smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg),
+ &client->tune_done);
+}
+
+static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+ int board_id = smscore_get_board_id(client->coredev);
+ struct sms_board *board = sms_get_board(board_id);
+ enum sms_device_type_st type = board->type;
+ int ret;
+
+ struct {
+ struct sms_msg_hdr msg;
+ u32 Data[4];
+ } msg;
+
+ fe->dtv_property_cache.delivery_system = SYS_ISDBT;
+
+ msg.msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
+ msg.msg.msg_dst_id = HIF_TASK;
+ msg.msg.msg_flags = 0;
+ msg.msg.msg_type = MSG_SMS_ISDBT_TUNE_REQ;
+ msg.msg.msg_length = sizeof(msg);
+
+ if (c->isdbt_sb_segment_idx == -1)
+ c->isdbt_sb_segment_idx = 0;
+
+ if (!c->isdbt_layer_enabled)
+ c->isdbt_layer_enabled = 7;
+
+ msg.Data[0] = c->frequency;
+ msg.Data[1] = BW_ISDBT_1SEG;
+ msg.Data[2] = 12000000;
+ msg.Data[3] = c->isdbt_sb_segment_idx;
+
+ if (c->isdbt_partial_reception) {
+ if ((type == SMS_PELE || type == SMS_RIO) &&
+ c->isdbt_sb_segment_count > 3)
+ msg.Data[1] = BW_ISDBT_13SEG;
+ else if (c->isdbt_sb_segment_count > 1)
+ msg.Data[1] = BW_ISDBT_3SEG;
+ } else if (type == SMS_PELE || type == SMS_RIO)
+ msg.Data[1] = BW_ISDBT_13SEG;
+
+ c->bandwidth_hz = 6000000;
+
+ sms_info("%s: freq %d segwidth %d segindex %d", __func__,
+ c->frequency, c->isdbt_sb_segment_count,
+ c->isdbt_sb_segment_idx);
+
+ /* Disable LNA, if any. An error is returned if no LNA is present */
+ ret = sms_board_lna_control(client->coredev, 0);
+ if (ret == 0) {
+ fe_status_t status;
+
+ /* tune with LNA off at first */
+ ret = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg),
+ &client->tune_done);
+
+ smsdvb_read_status(fe, &status);
+
+ if (status & FE_HAS_LOCK)
+ return ret;
+
+ /* previous tune didn't lock - enable LNA and tune again */
+ sms_board_lna_control(client->coredev, 1);
+ }
+ return smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg),
+ &client->tune_done);
+}
+
+static int smsdvb_set_frontend(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+ struct smscore_device_t *coredev = client->coredev;
+
+ smsdvb_stats_not_ready(fe);
+ c->strength.stat[0].uvalue = 0;
+ c->cnr.stat[0].uvalue = 0;
+
+ client->has_tuned = false;
+
+ switch (smscore_get_device_mode(coredev)) {
+ case DEVICE_MODE_DVBT:
+ case DEVICE_MODE_DVBT_BDA:
+ return smsdvb_dvbt_set_frontend(fe);
+ case DEVICE_MODE_ISDBT:
+ case DEVICE_MODE_ISDBT_BDA:
+ return smsdvb_isdbt_set_frontend(fe);
+ default:
+ return -EINVAL;
+ }
+}
+
+/* Nothing to do here, as stats are automatically updated */
+static int smsdvb_get_frontend(struct dvb_frontend *fe)
+{
+ return 0;
+}
+
+static int smsdvb_init(struct dvb_frontend *fe)
+{
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+
+ sms_board_power(client->coredev, 1);
+
+ sms_board_dvb3_event(client, DVB3_EVENT_INIT);
+ return 0;
+}
+
+static int smsdvb_sleep(struct dvb_frontend *fe)
+{
+ struct smsdvb_client_t *client =
+ container_of(fe, struct smsdvb_client_t, frontend);
+
+ sms_board_led_feedback(client->coredev, SMS_LED_OFF);
+ sms_board_power(client->coredev, 0);
+
+ sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
+
+ return 0;
+}
+
+static void smsdvb_release(struct dvb_frontend *fe)
+{
+ /* do nothing */
+}
+
+static struct dvb_frontend_ops smsdvb_fe_ops = {
+ .info = {
+ .name = "Siano Mobile Digital MDTV Receiver",
+ .frequency_min = 44250000,
+ .frequency_max = 867250000,
+ .frequency_stepsize = 250000,
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+ FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+ FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_RECOVER |
+ FE_CAN_HIERARCHY_AUTO,
+ },
+
+ .release = smsdvb_release,
+
+ .set_frontend = smsdvb_set_frontend,
+ .get_frontend = smsdvb_get_frontend,
+ .get_tune_settings = smsdvb_get_tune_settings,
+
+ .read_status = smsdvb_read_status,
+ .read_ber = smsdvb_read_ber,
+ .read_signal_strength = smsdvb_read_signal_strength,
+ .read_snr = smsdvb_read_snr,
+ .read_ucblocks = smsdvb_read_ucblocks,
+
+ .init = smsdvb_init,
+ .sleep = smsdvb_sleep,
+};
+
+static int smsdvb_hotplug(struct smscore_device_t *coredev,
+ struct device *device, int arrival)
+{
+ struct smsclient_params_t params;
+ struct smsdvb_client_t *client;
+ int rc;
+
+ /* device removal handled by onremove callback */
+ if (!arrival)
+ return 0;
+ client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
+ if (!client) {
+ sms_err("kmalloc() failed");
+ return -ENOMEM;
+ }
+
+ /* register dvb adapter */
+ rc = dvb_register_adapter(&client->adapter,
+ sms_get_board(
+ smscore_get_board_id(coredev))->name,
+ THIS_MODULE, device, adapter_nr);
+ if (rc < 0) {
+ sms_err("dvb_register_adapter() failed %d", rc);
+ goto adapter_error;
+ }
+
+ /* init dvb demux */
+ client->demux.dmx.capabilities = DMX_TS_FILTERING;
+ client->demux.filternum = 32; /* todo: nova ??? */
+ client->demux.feednum = 32;
+ client->demux.start_feed = smsdvb_start_feed;
+ client->demux.stop_feed = smsdvb_stop_feed;
+
+ rc = dvb_dmx_init(&client->demux);
+ if (rc < 0) {
+ sms_err("dvb_dmx_init failed %d", rc);
+ goto dvbdmx_error;
+ }
+
+ /* init dmxdev */
+ client->dmxdev.filternum = 32;
+ client->dmxdev.demux = &client->demux.dmx;
+ client->dmxdev.capabilities = 0;
+
+ rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
+ if (rc < 0) {
+ sms_err("dvb_dmxdev_init failed %d", rc);
+ goto dmxdev_error;
+ }
+
+ /* init and register frontend */
+ memcpy(&client->frontend.ops, &smsdvb_fe_ops,
+ sizeof(struct dvb_frontend_ops));
+
+ switch (smscore_get_device_mode(coredev)) {
+ case DEVICE_MODE_DVBT:
+ case DEVICE_MODE_DVBT_BDA:
+ client->frontend.ops.delsys[0] = SYS_DVBT;
+ break;
+ case DEVICE_MODE_ISDBT:
+ case DEVICE_MODE_ISDBT_BDA:
+ client->frontend.ops.delsys[0] = SYS_ISDBT;
+ break;
+ }
+
+ rc = dvb_register_frontend(&client->adapter, &client->frontend);
+ if (rc < 0) {
+ sms_err("frontend registration failed %d", rc);
+ goto frontend_error;
+ }
+
+ params.initial_id = 1;
+ params.data_type = MSG_SMS_DVBT_BDA_DATA;
+ params.onresponse_handler = smsdvb_onresponse;
+ params.onremove_handler = smsdvb_onremove;
+ params.context = client;
+
+ rc = smscore_register_client(coredev, &params, &client->smsclient);
+ if (rc < 0) {
+ sms_err("smscore_register_client() failed %d", rc);
+ goto client_error;
+ }
+
+ client->coredev = coredev;
+
+ init_completion(&client->tune_done);
+ init_completion(&client->stats_done);
+
+ kmutex_lock(&g_smsdvb_clientslock);
+
+ list_add(&client->entry, &g_smsdvb_clients);
+
+ kmutex_unlock(&g_smsdvb_clientslock);
+
+ client->event_fe_state = -1;
+ client->event_unc_state = -1;
+ sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
+
+ sms_info("success");
+ sms_board_setup(coredev);
+
+ if (smsdvb_debugfs_create(client) < 0)
+ sms_info("failed to create debugfs node");
+
+ return 0;
+
+client_error:
+ dvb_unregister_frontend(&client->frontend);
+
+frontend_error:
+ dvb_dmxdev_release(&client->dmxdev);
+
+dmxdev_error:
+ dvb_dmx_release(&client->demux);
+
+dvbdmx_error:
+ dvb_unregister_adapter(&client->adapter);
+
+adapter_error:
+ kfree(client);
+ return rc;
+}
+
+static int __init smsdvb_module_init(void)
+{
+ int rc;
+
+ INIT_LIST_HEAD(&g_smsdvb_clients);
+ kmutex_init(&g_smsdvb_clientslock);
+
+ smsdvb_debugfs_register();
+
+ rc = smscore_register_hotplug(smsdvb_hotplug);
+
+ sms_debug("");
+
+ return rc;
+}
+
+static void __exit smsdvb_module_exit(void)
+{
+ smscore_unregister_hotplug(smsdvb_hotplug);
+
+ kmutex_lock(&g_smsdvb_clientslock);
+
+ while (!list_empty(&g_smsdvb_clients))
+ smsdvb_unregister_client((struct smsdvb_client_t *)g_smsdvb_clients.next);
+
+ smsdvb_debugfs_unregister();
+
+ kmutex_unlock(&g_smsdvb_clientslock);
+}
+
+module_init(smsdvb_module_init);
+module_exit(smsdvb_module_exit);
+
+MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
+MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c
deleted file mode 100644
index aa77e54a8fa..00000000000
--- a/drivers/media/common/siano/smsdvb.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2008, Uri Shkolnik
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-
-#include "smscoreapi.h"
-#include "smsendian.h"
-#include "sms-cards.h"
-
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-
-struct smsdvb_client_t {
- struct list_head entry;
-
- struct smscore_device_t *coredev;
- struct smscore_client_t *smsclient;
-
- struct dvb_adapter adapter;
- struct dvb_demux demux;
- struct dmxdev dmxdev;
- struct dvb_frontend frontend;
-
- fe_status_t fe_status;
-
- struct completion tune_done;
-
- struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb;
- int event_fe_state;
- int event_unc_state;
-};
-
-static struct list_head g_smsdvb_clients;
-static struct mutex g_smsdvb_clientslock;
-
-static int sms_dbg;
-module_param_named(debug, sms_dbg, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
-
-/* Events that may come from DVB v3 adapter */
-static void sms_board_dvb3_event(struct smsdvb_client_t *client,
- enum SMS_DVB3_EVENTS event) {
-
- struct smscore_device_t *coredev = client->coredev;
- switch (event) {
- case DVB3_EVENT_INIT:
- sms_debug("DVB3_EVENT_INIT");
- sms_board_event(coredev, BOARD_EVENT_BIND);
- break;
- case DVB3_EVENT_SLEEP:
- sms_debug("DVB3_EVENT_SLEEP");
- sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
- break;
- case DVB3_EVENT_HOTPLUG:
- sms_debug("DVB3_EVENT_HOTPLUG");
- sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
- break;
- case DVB3_EVENT_FE_LOCK:
- if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
- client->event_fe_state = DVB3_EVENT_FE_LOCK;
- sms_debug("DVB3_EVENT_FE_LOCK");
- sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
- }
- break;
- case DVB3_EVENT_FE_UNLOCK:
- if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
- client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
- sms_debug("DVB3_EVENT_FE_UNLOCK");
- sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
- }
- break;
- case DVB3_EVENT_UNC_OK:
- if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
- client->event_unc_state = DVB3_EVENT_UNC_OK;
- sms_debug("DVB3_EVENT_UNC_OK");
- sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
- }
- break;
- case DVB3_EVENT_UNC_ERR:
- if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
- client->event_unc_state = DVB3_EVENT_UNC_ERR;
- sms_debug("DVB3_EVENT_UNC_ERR");
- sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
- }
- break;
-
- default:
- sms_err("Unknown dvb3 api event");
- break;
- }
-}
-
-
-static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
- struct SMSHOSTLIB_STATISTICS_ST *p)
-{
- if (sms_dbg & 2) {
- printk(KERN_DEBUG "Reserved = %d", p->Reserved);
- printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
- printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
- printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
- printk(KERN_DEBUG "SNR = %d", p->SNR);
- printk(KERN_DEBUG "BER = %d", p->BER);
- printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC);
- printk(KERN_DEBUG "TS_PER = %d", p->TS_PER);
- printk(KERN_DEBUG "MFER = %d", p->MFER);
- printk(KERN_DEBUG "RSSI = %d", p->RSSI);
- printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
- printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
- printk(KERN_DEBUG "Frequency = %d", p->Frequency);
- printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
- printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
- printk(KERN_DEBUG "ModemState = %d", p->ModemState);
- printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
- printk(KERN_DEBUG "CodeRate = %d", p->CodeRate);
- printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate);
- printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy);
- printk(KERN_DEBUG "Constellation = %d", p->Constellation);
- printk(KERN_DEBUG "BurstSize = %d", p->BurstSize);
- printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration);
- printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime);
- printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime);
- printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows);
- printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols);
- printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols);
- printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets);
- printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets);
- printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs);
- printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs);
- printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs);
- printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount);
- printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount);
- printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
- printk(KERN_DEBUG "PreBER = %d", p->PreBER);
- printk(KERN_DEBUG "CellId = %d", p->CellId);
- printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP);
- printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP);
- printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived);
- }
-
- pReceptionData->IsDemodLocked = p->IsDemodLocked;
-
- pReceptionData->SNR = p->SNR;
- pReceptionData->BER = p->BER;
- pReceptionData->BERErrorCount = p->BERErrorCount;
- pReceptionData->InBandPwr = p->InBandPwr;
- pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
-};
-
-
-static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
- struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
-{
- int i;
-
- if (sms_dbg & 2) {
- printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
- printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
- printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
- printk(KERN_DEBUG "SNR = %d", p->SNR);
- printk(KERN_DEBUG "RSSI = %d", p->RSSI);
- printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
- printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
- printk(KERN_DEBUG "Frequency = %d", p->Frequency);
- printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
- printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
- printk(KERN_DEBUG "ModemState = %d", p->ModemState);
- printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
- printk(KERN_DEBUG "SystemType = %d", p->SystemType);
- printk(KERN_DEBUG "PartialReception = %d", p->PartialReception);
- printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers);
- printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
-
- for (i = 0; i < 3; i++) {
- printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate);
- printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation);
- printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER);
- printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount);
- printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount);
- printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER);
- printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER);
- printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets);
- printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets);
- printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI);
- printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments);
- printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors);
- }
- }
-
- pReceptionData->IsDemodLocked = p->IsDemodLocked;
-
- pReceptionData->SNR = p->SNR;
- pReceptionData->InBandPwr = p->InBandPwr;
-
- pReceptionData->ErrorTSPackets = 0;
- pReceptionData->BER = 0;
- pReceptionData->BERErrorCount = 0;
- for (i = 0; i < 3; i++) {
- pReceptionData->BER += p->LayerInfo[i].BER;
- pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount;
- pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets;
- }
-}
-
-static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
-{
- struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
- struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p)
- + cb->offset);
- u32 *pMsgData = (u32 *) phdr + 1;
- /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/
- bool is_status_update = false;
-
- smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr);
-
- switch (phdr->msgType) {
- case MSG_SMS_DVBT_BDA_DATA:
- dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1),
- cb->size - sizeof(struct SmsMsgHdr_ST));
- break;
-
- case MSG_SMS_RF_TUNE_RES:
- case MSG_SMS_ISDBT_TUNE_RES:
- complete(&client->tune_done);
- break;
-
- case MSG_SMS_SIGNAL_DETECTED_IND:
- sms_info("MSG_SMS_SIGNAL_DETECTED_IND");
- client->sms_stat_dvb.TransmissionData.IsDemodLocked = true;
- is_status_update = true;
- break;
-
- case MSG_SMS_NO_SIGNAL_IND:
- sms_info("MSG_SMS_NO_SIGNAL_IND");
- client->sms_stat_dvb.TransmissionData.IsDemodLocked = false;
- is_status_update = true;
- break;
-
- case MSG_SMS_TRANSMISSION_IND: {
- sms_info("MSG_SMS_TRANSMISSION_IND");
-
- pMsgData++;
- memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData,
- sizeof(struct TRANSMISSION_STATISTICS_S));
-
- /* Mo need to correct guard interval
- * (as opposed to old statistics message).
- */
- CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData);
- CORRECT_STAT_TRANSMISSON_MODE(
- client->sms_stat_dvb.TransmissionData);
- is_status_update = true;
- break;
- }
- case MSG_SMS_HO_PER_SLICES_IND: {
- struct RECEPTION_STATISTICS_S *pReceptionData =
- &client->sms_stat_dvb.ReceptionData;
- struct SRVM_SIGNAL_STATUS_S SignalStatusData;
-
- /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/
- pMsgData++;
- SignalStatusData.result = pMsgData[0];
- SignalStatusData.snr = pMsgData[1];
- SignalStatusData.inBandPower = (s32) pMsgData[2];
- SignalStatusData.tsPackets = pMsgData[3];
- SignalStatusData.etsPackets = pMsgData[4];
- SignalStatusData.constellation = pMsgData[5];
- SignalStatusData.hpCode = pMsgData[6];
- SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03;
- SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03;
- SignalStatusData.cellId = pMsgData[9] & 0xFFFF;
- SignalStatusData.reason = pMsgData[10];
- SignalStatusData.requestId = pMsgData[11];
- pReceptionData->IsRfLocked = pMsgData[16];
- pReceptionData->IsDemodLocked = pMsgData[17];
- pReceptionData->ModemState = pMsgData[12];
- pReceptionData->SNR = pMsgData[1];
- pReceptionData->BER = pMsgData[13];
- pReceptionData->RSSI = pMsgData[14];
- CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);
-
- pReceptionData->InBandPwr = (s32) pMsgData[2];
- pReceptionData->CarrierOffset = (s32) pMsgData[15];
- pReceptionData->TotalTSPackets = pMsgData[3];
- pReceptionData->ErrorTSPackets = pMsgData[4];
-
- /* TS PER */
- if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
- > 0) {
- pReceptionData->TS_PER = (SignalStatusData.etsPackets
- * 100) / (SignalStatusData.tsPackets
- + SignalStatusData.etsPackets);
- } else {
- pReceptionData->TS_PER = 0;
- }
-
- pReceptionData->BERBitCount = pMsgData[18];
- pReceptionData->BERErrorCount = pMsgData[19];
-
- pReceptionData->MRC_SNR = pMsgData[20];
- pReceptionData->MRC_InBandPwr = pMsgData[21];
- pReceptionData->MRC_RSSI = pMsgData[22];
-
- is_status_update = true;
- break;
- }
- case MSG_SMS_GET_STATISTICS_RES: {
- union {
- struct SMSHOSTLIB_STATISTICS_ISDBT_ST isdbt;
- struct SmsMsgStatisticsInfo_ST dvb;
- } *p = (void *) (phdr + 1);
- struct RECEPTION_STATISTICS_S *pReceptionData =
- &client->sms_stat_dvb.ReceptionData;
-
- sms_info("MSG_SMS_GET_STATISTICS_RES");
-
- is_status_update = true;
-
- switch (smscore_get_device_mode(client->coredev)) {
- case DEVICE_MODE_ISDBT:
- case DEVICE_MODE_ISDBT_BDA:
- smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt);
- break;
- default:
- smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat);
- }
- if (!pReceptionData->IsDemodLocked) {
- pReceptionData->SNR = 0;
- pReceptionData->BER = 0;
- pReceptionData->BERErrorCount = 0;
- pReceptionData->InBandPwr = 0;
- pReceptionData->ErrorTSPackets = 0;
- }
-
- complete(&client->tune_done);
- break;
- }
- default:
- sms_info("Unhandled message %d", phdr->msgType);
-
- }
- smscore_putbuffer(client->coredev, cb);
-
- if (is_status_update) {
- if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) {
- client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER
- | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
- sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
- if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets
- == 0)
- sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
- else
- sms_board_dvb3_event(client,
- DVB3_EVENT_UNC_ERR);
-
- } else {
- if (client->sms_stat_dvb.ReceptionData.IsRfLocked)
- client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
- else
- client->fe_status = 0;
- sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
- }
- }
-
- return 0;
-}
-
-static void smsdvb_unregister_client(struct smsdvb_client_t *client)
-{
- /* must be called under clientslock */
-
- list_del(&client->entry);
-
- smscore_unregister_client(client->smsclient);
- dvb_unregister_frontend(&client->frontend);
- dvb_dmxdev_release(&client->dmxdev);
- dvb_dmx_release(&client->demux);
- dvb_unregister_adapter(&client->adapter);
- kfree(client);
-}
-
-static void smsdvb_onremove(void *context)
-{
- kmutex_lock(&g_smsdvb_clientslock);
-
- smsdvb_unregister_client((struct smsdvb_client_t *) context);
-
- kmutex_unlock(&g_smsdvb_clientslock);
-}
-
-static int smsdvb_start_feed(struct dvb_demux_feed *feed)
-{
- struct smsdvb_client_t *client =
- container_of(feed->demux, struct smsdvb_client_t, demux);
- struct SmsMsgData_ST PidMsg;
-
- sms_debug("add pid %d(%x)",
- feed->pid, feed->pid);
-
- PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
- PidMsg.xMsgHeader.msgDstId = HIF_TASK;
- PidMsg.xMsgHeader.msgFlags = 0;
- PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ;
- PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
- PidMsg.msgData[0] = feed->pid;
-
- smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
- return smsclient_sendrequest(client->smsclient,
- &PidMsg, sizeof(PidMsg));
-}
-
-static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
-{
- struct smsdvb_client_t *client =
- container_of(feed->demux, struct smsdvb_client_t, demux);
- struct SmsMsgData_ST PidMsg;
-
- sms_debug("remove pid %d(%x)",
- feed->pid, feed->pid);
-
- PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
- PidMsg.xMsgHeader.msgDstId = HIF_TASK;
- PidMsg.xMsgHeader.msgFlags = 0;
- PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ;
- PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
- PidMsg.msgData[0] = feed->pid;
-
- smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
- return smsclient_sendrequest(client->smsclient,
- &PidMsg, sizeof(PidMsg));
-}
-
-static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
- void *buffer, size_t size,
- struct completion *completion)
-{
- int rc;
-
- smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer);
- rc = smsclient_sendrequest(client->smsclient, buffer, size);
- if (rc < 0)
- return rc;
-
- return wait_for_completion_timeout(completion,
- msecs_to_jiffies(2000)) ?
- 0 : -ETIME;
-}
-
-static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
-{
- int rc;
- struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
- DVBT_BDA_CONTROL_MSG_ID,
- HIF_TASK,
- sizeof(struct SmsMsgHdr_ST), 0 };
-
- rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
- &client->tune_done);
-
- return rc;
-}
-
-static inline int led_feedback(struct smsdvb_client_t *client)
-{
- if (client->fe_status & FE_HAS_LOCK)
- return sms_board_led_feedback(client->coredev,
- (client->sms_stat_dvb.ReceptionData.BER
- == 0) ? SMS_LED_HI : SMS_LED_LO);
- else
- return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
-}
-
-static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
-{
- int rc;
- struct smsdvb_client_t *client;
- client = container_of(fe, struct smsdvb_client_t, frontend);
-
- rc = smsdvb_send_statistics_request(client);
-
- *stat = client->fe_status;
-
- led_feedback(client);
-
- return rc;
-}
-
-static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
-{
- int rc;
- struct smsdvb_client_t *client;
- client = container_of(fe, struct smsdvb_client_t, frontend);
-
- rc = smsdvb_send_statistics_request(client);
-
- *ber = client->sms_stat_dvb.ReceptionData.BER;
-
- led_feedback(client);
-
- return rc;
-}
-
-static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
- int rc;
-
- struct smsdvb_client_t *client;
- client = container_of(fe, struct smsdvb_client_t, frontend);
-
- rc = smsdvb_send_statistics_request(client);
-
- if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
- *strength = 0;
- else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
- *strength = 100;
- else
- *strength =
- (client->sms_stat_dvb.ReceptionData.InBandPwr
- + 95) * 3 / 2;
-
- led_feedback(client);
-
- return rc;
-}
-
-static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
- int rc;
- struct smsdvb_client_t *client;
- client = container_of(fe, struct smsdvb_client_t, frontend);
-
- rc = smsdvb_send_statistics_request(client);
-
- *snr = client->sms_stat_dvb.ReceptionData.SNR;
-
- led_feedback(client);
-
- return rc;
-}
-
-static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
-{
- int rc;
- struct smsdvb_client_t *client;
- client = container_of(fe, struct smsdvb_client_t, frontend);
-
- rc = smsdvb_send_statistics_request(client);
-
- *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
-
- led_feedback(client);
-
- return rc;
-}
-
-static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
- struct dvb_frontend_tune_settings *tune)
-{
- sms_debug("");
-
- tune->min_delay_ms = 400;
- tune->step_size = 250000;
- tune->max_drift = 0;
- return 0;
-}
-
-static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- struct smsdvb_client_t *client =
- container_of(fe, struct smsdvb_client_t, frontend);
-
- struct {
- struct SmsMsgHdr_ST Msg;
- u32 Data[3];
- } Msg;
-
- int ret;
-
- client->fe_status = FE_HAS_SIGNAL;
- client->event_fe_state = -1;
- client->event_unc_state = -1;
- fe->dtv_property_cache.delivery_system = SYS_DVBT;
-
- Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
- Msg.Msg.msgDstId = HIF_TASK;
- Msg.Msg.msgFlags = 0;
- Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
- Msg.Msg.msgLength = sizeof(Msg);
- Msg.Data[0] = c->frequency;
- Msg.Data[2] = 12000000;
-
- sms_info("%s: freq %d band %d", __func__, c->frequency,
- c->bandwidth_hz);
-
- switch (c->bandwidth_hz / 1000000) {
- case 8:
- Msg.Data[1] = BW_8_MHZ;
- break;
- case 7:
- Msg.Data[1] = BW_7_MHZ;
- break;
- case 6:
- Msg.Data[1] = BW_6_MHZ;
- break;
- case 0:
- return -EOPNOTSUPP;
- default:
- return -EINVAL;
- }
- /* Disable LNA, if any. An error is returned if no LNA is present */
- ret = sms_board_lna_control(client->coredev, 0);
- if (ret == 0) {
- fe_status_t status;
-
- /* tune with LNA off at first */
- ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
- &client->tune_done);
-
- smsdvb_read_status(fe, &status);
-
- if (status & FE_HAS_LOCK)
- return ret;
-
- /* previous tune didn't lock - enable LNA and tune again */
- sms_board_lna_control(client->coredev, 1);
- }
-
- return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
- &client->tune_done);
-}
-
-static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- struct smsdvb_client_t *client =
- container_of(fe, struct smsdvb_client_t, frontend);
-
- struct {
- struct SmsMsgHdr_ST Msg;
- u32 Data[4];
- } Msg;
-
- fe->dtv_property_cache.delivery_system = SYS_ISDBT;
-
- Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
- Msg.Msg.msgDstId = HIF_TASK;
- Msg.Msg.msgFlags = 0;
- Msg.Msg.msgType = MSG_SMS_ISDBT_TUNE_REQ;
- Msg.Msg.msgLength = sizeof(Msg);
-
- if (c->isdbt_sb_segment_idx == -1)
- c->isdbt_sb_segment_idx = 0;
-
- switch (c->isdbt_sb_segment_count) {
- case 3:
- Msg.Data[1] = BW_ISDBT_3SEG;
- break;
- case 1:
- Msg.Data[1] = BW_ISDBT_1SEG;
- break;
- case 0: /* AUTO */
- switch (c->bandwidth_hz / 1000000) {
- case 8:
- case 7:
- c->isdbt_sb_segment_count = 3;
- Msg.Data[1] = BW_ISDBT_3SEG;
- break;
- case 6:
- c->isdbt_sb_segment_count = 1;
- Msg.Data[1] = BW_ISDBT_1SEG;
- break;
- default: /* Assumes 6 MHZ bw */
- c->isdbt_sb_segment_count = 1;
- c->bandwidth_hz = 6000;
- Msg.Data[1] = BW_ISDBT_1SEG;
- break;
- }
- break;
- default:
- sms_info("Segment count %d not supported", c->isdbt_sb_segment_count);
- return -EINVAL;
- }
-
- Msg.Data[0] = c->frequency;
- Msg.Data[2] = 12000000;
- Msg.Data[3] = c->isdbt_sb_segment_idx;
-
- sms_info("%s: freq %d segwidth %d segindex %d\n", __func__,
- c->frequency, c->isdbt_sb_segment_count,
- c->isdbt_sb_segment_idx);
-
- return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
- &client->tune_done);
-}
-
-static int smsdvb_set_frontend(struct dvb_frontend *fe)
-{
- struct smsdvb_client_t *client =
- container_of(fe, struct smsdvb_client_t, frontend);
- struct smscore_device_t *coredev = client->coredev;
-
- switch (smscore_get_device_mode(coredev)) {
- case DEVICE_MODE_DVBT:
- case DEVICE_MODE_DVBT_BDA:
- return smsdvb_dvbt_set_frontend(fe);
- case DEVICE_MODE_ISDBT:
- case DEVICE_MODE_ISDBT_BDA:
- return smsdvb_isdbt_set_frontend(fe);
- default:
- return -EINVAL;
- }
-}
-
-static int smsdvb_get_frontend(struct dvb_frontend *fe)
-{
- struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
- struct smsdvb_client_t *client =
- container_of(fe, struct smsdvb_client_t, frontend);
- struct smscore_device_t *coredev = client->coredev;
- struct TRANSMISSION_STATISTICS_S *td =
- &client->sms_stat_dvb.TransmissionData;
-
- switch (smscore_get_device_mode(coredev)) {
- case DEVICE_MODE_DVBT:
- case DEVICE_MODE_DVBT_BDA:
- fep->frequency = td->Frequency;
-
- switch (td->Bandwidth) {
- case 6:
- fep->bandwidth_hz = 6000000;
- break;
- case 7:
- fep->bandwidth_hz = 7000000;
- break;
- case 8:
- fep->bandwidth_hz = 8000000;
- break;
- }
-
- switch (td->TransmissionMode) {
- case 2:
- fep->transmission_mode = TRANSMISSION_MODE_2K;
- break;
- case 8:
- fep->transmission_mode = TRANSMISSION_MODE_8K;
- }
-
- switch (td->GuardInterval) {
- case 0:
- fep->guard_interval = GUARD_INTERVAL_1_32;
- break;
- case 1:
- fep->guard_interval = GUARD_INTERVAL_1_16;
- break;
- case 2:
- fep->guard_interval = GUARD_INTERVAL_1_8;
- break;
- case 3:
- fep->guard_interval = GUARD_INTERVAL_1_4;
- break;
- }
-
- switch (td->CodeRate) {
- case 0:
- fep->code_rate_HP = FEC_1_2;
- break;
- case 1:
- fep->code_rate_HP = FEC_2_3;
- break;
- case 2:
- fep->code_rate_HP = FEC_3_4;
- break;
- case 3:
- fep->code_rate_HP = FEC_5_6;
- break;
- case 4:
- fep->code_rate_HP = FEC_7_8;
- break;
- }
-
- switch (td->LPCodeRate) {
- case 0:
- fep->code_rate_LP = FEC_1_2;
- break;
- case 1:
- fep->code_rate_LP = FEC_2_3;
- break;
- case 2:
- fep->code_rate_LP = FEC_3_4;
- break;
- case 3:
- fep->code_rate_LP = FEC_5_6;
- break;
- case 4:
- fep->code_rate_LP = FEC_7_8;
- break;
- }
-
- switch (td->Constellation) {
- case 0:
- fep->modulation = QPSK;
- break;
- case 1:
- fep->modulation = QAM_16;
- break;
- case 2:
- fep->modulation = QAM_64;
- break;
- }
-
- switch (td->Hierarchy) {
- case 0:
- fep->hierarchy = HIERARCHY_NONE;
- break;
- case 1:
- fep->hierarchy = HIERARCHY_1;
- break;
- case 2:
- fep->hierarchy = HIERARCHY_2;
- break;
- case 3:
- fep->hierarchy = HIERARCHY_4;
- break;
- }
-
- fep->inversion = INVERSION_AUTO;
- break;
- case DEVICE_MODE_ISDBT:
- case DEVICE_MODE_ISDBT_BDA:
- fep->frequency = td->Frequency;
- fep->bandwidth_hz = 6000000;
- /* todo: retrive the other parameters */
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int smsdvb_init(struct dvb_frontend *fe)
-{
- struct smsdvb_client_t *client =
- container_of(fe, struct smsdvb_client_t, frontend);
-
- sms_board_power(client->coredev, 1);
-
- sms_board_dvb3_event(client, DVB3_EVENT_INIT);
- return 0;
-}
-
-static int smsdvb_sleep(struct dvb_frontend *fe)
-{
- struct smsdvb_client_t *client =
- container_of(fe, struct smsdvb_client_t, frontend);
-
- sms_board_led_feedback(client->coredev, SMS_LED_OFF);
- sms_board_power(client->coredev, 0);
-
- sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
-
- return 0;
-}
-
-static void smsdvb_release(struct dvb_frontend *fe)
-{
- /* do nothing */
-}
-
-static struct dvb_frontend_ops smsdvb_fe_ops = {
- .info = {
- .name = "Siano Mobile Digital MDTV Receiver",
- .frequency_min = 44250000,
- .frequency_max = 867250000,
- .frequency_stepsize = 250000,
- .caps = FE_CAN_INVERSION_AUTO |
- FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
- FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
- FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
- FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
- FE_CAN_GUARD_INTERVAL_AUTO |
- FE_CAN_RECOVER |
- FE_CAN_HIERARCHY_AUTO,
- },
-
- .release = smsdvb_release,
-
- .set_frontend = smsdvb_set_frontend,
- .get_frontend = smsdvb_get_frontend,
- .get_tune_settings = smsdvb_get_tune_settings,
-
- .read_status = smsdvb_read_status,
- .read_ber = smsdvb_read_ber,
- .read_signal_strength = smsdvb_read_signal_strength,
- .read_snr = smsdvb_read_snr,
- .read_ucblocks = smsdvb_read_ucblocks,
-
- .init = smsdvb_init,
- .sleep = smsdvb_sleep,
-};
-
-static int smsdvb_hotplug(struct smscore_device_t *coredev,
- struct device *device, int arrival)
-{
- struct smsclient_params_t params;
- struct smsdvb_client_t *client;
- int rc;
-
- /* device removal handled by onremove callback */
- if (!arrival)
- return 0;
- client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
- if (!client) {
- sms_err("kmalloc() failed");
- return -ENOMEM;
- }
-
- /* register dvb adapter */
- rc = dvb_register_adapter(&client->adapter,
- sms_get_board(
- smscore_get_board_id(coredev))->name,
- THIS_MODULE, device, adapter_nr);
- if (rc < 0) {
- sms_err("dvb_register_adapter() failed %d", rc);
- goto adapter_error;
- }
-
- /* init dvb demux */
- client->demux.dmx.capabilities = DMX_TS_FILTERING;
- client->demux.filternum = 32; /* todo: nova ??? */
- client->demux.feednum = 32;
- client->demux.start_feed = smsdvb_start_feed;
- client->demux.stop_feed = smsdvb_stop_feed;
-
- rc = dvb_dmx_init(&client->demux);
- if (rc < 0) {
- sms_err("dvb_dmx_init failed %d", rc);
- goto dvbdmx_error;
- }
-
- /* init dmxdev */
- client->dmxdev.filternum = 32;
- client->dmxdev.demux = &client->demux.dmx;
- client->dmxdev.capabilities = 0;
-
- rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
- if (rc < 0) {
- sms_err("dvb_dmxdev_init failed %d", rc);
- goto dmxdev_error;
- }
-
- /* init and register frontend */
- memcpy(&client->frontend.ops, &smsdvb_fe_ops,
- sizeof(struct dvb_frontend_ops));
-
- switch (smscore_get_device_mode(coredev)) {
- case DEVICE_MODE_DVBT:
- case DEVICE_MODE_DVBT_BDA:
- client->frontend.ops.delsys[0] = SYS_DVBT;
- break;
- case DEVICE_MODE_ISDBT:
- case DEVICE_MODE_ISDBT_BDA:
- client->frontend.ops.delsys[0] = SYS_ISDBT;
- break;
- }
-
- rc = dvb_register_frontend(&client->adapter, &client->frontend);
- if (rc < 0) {
- sms_err("frontend registration failed %d", rc);
- goto frontend_error;
- }
-
- params.initial_id = 1;
- params.data_type = MSG_SMS_DVBT_BDA_DATA;
- params.onresponse_handler = smsdvb_onresponse;
- params.onremove_handler = smsdvb_onremove;
- params.context = client;
-
- rc = smscore_register_client(coredev, &params, &client->smsclient);
- if (rc < 0) {
- sms_err("smscore_register_client() failed %d", rc);
- goto client_error;
- }
-
- client->coredev = coredev;
-
- init_completion(&client->tune_done);
-
- kmutex_lock(&g_smsdvb_clientslock);
-
- list_add(&client->entry, &g_smsdvb_clients);
-
- kmutex_unlock(&g_smsdvb_clientslock);
-
- client->event_fe_state = -1;
- client->event_unc_state = -1;
- sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
-
- sms_info("success");
- sms_board_setup(coredev);
-
- return 0;
-
-client_error:
- dvb_unregister_frontend(&client->frontend);
-
-frontend_error:
- dvb_dmxdev_release(&client->dmxdev);
-
-dmxdev_error:
- dvb_dmx_release(&client->demux);
-
-dvbdmx_error:
- dvb_unregister_adapter(&client->adapter);
-
-adapter_error:
- kfree(client);
- return rc;
-}
-
-static int __init smsdvb_module_init(void)
-{
- int rc;
-
- INIT_LIST_HEAD(&g_smsdvb_clients);
- kmutex_init(&g_smsdvb_clientslock);
-
- rc = smscore_register_hotplug(smsdvb_hotplug);
-
- sms_debug("");
-
- return rc;
-}
-
-static void __exit smsdvb_module_exit(void)
-{
- smscore_unregister_hotplug(smsdvb_hotplug);
-
- kmutex_lock(&g_smsdvb_clientslock);
-
- while (!list_empty(&g_smsdvb_clients))
- smsdvb_unregister_client(
- (struct smsdvb_client_t *) g_smsdvb_clients.next);
-
- kmutex_unlock(&g_smsdvb_clientslock);
-}
-
-module_init(smsdvb_module_init);
-module_exit(smsdvb_module_exit);
-
-MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
-MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/siano/smsdvb.h b/drivers/media/common/siano/smsdvb.h
new file mode 100644
index 00000000000..ae36d0ae0fb
--- /dev/null
+++ b/drivers/media/common/siano/smsdvb.h
@@ -0,0 +1,130 @@
+/***********************************************************************
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+
+ * 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, see <http://www.gnu.org/licenses/>.
+ *
+ ***********************************************************************/
+
+struct smsdvb_debugfs;
+struct smsdvb_client_t;
+
+typedef void (*sms_prt_dvb_stats_t)(struct smsdvb_debugfs *debug_data,
+ struct sms_stats *p);
+
+typedef void (*sms_prt_isdb_stats_t)(struct smsdvb_debugfs *debug_data,
+ struct sms_isdbt_stats *p);
+
+typedef void (*sms_prt_isdb_stats_ex_t)
+ (struct smsdvb_debugfs *debug_data,
+ struct sms_isdbt_stats_ex *p);
+
+
+struct smsdvb_client_t {
+ struct list_head entry;
+
+ struct smscore_device_t *coredev;
+ struct smscore_client_t *smsclient;
+
+ struct dvb_adapter adapter;
+ struct dvb_demux demux;
+ struct dmxdev dmxdev;
+ struct dvb_frontend frontend;
+
+ fe_status_t fe_status;
+
+ struct completion tune_done;
+ struct completion stats_done;
+
+ int last_per;
+
+ int legacy_ber, legacy_per;
+
+ int event_fe_state;
+ int event_unc_state;
+
+ unsigned long get_stats_jiffies;
+
+ int feed_users;
+ bool has_tuned;
+
+ /* stats debugfs data */
+ struct dentry *debugfs;
+
+ struct smsdvb_debugfs *debug_data;
+
+ sms_prt_dvb_stats_t prt_dvb_stats;
+ sms_prt_isdb_stats_t prt_isdb_stats;
+ sms_prt_isdb_stats_ex_t prt_isdb_stats_ex;
+};
+
+/*
+ * This struct is a mix of struct sms_rx_stats_ex and
+ * struct sms_srvm_signal_status.
+ * It was obtained by comparing the way it was filled by the original code
+ */
+struct RECEPTION_STATISTICS_PER_SLICES_S {
+ u32 result;
+ u32 snr;
+ s32 in_band_power;
+ u32 ts_packets;
+ u32 ets_packets;
+ u32 constellation;
+ u32 hp_code;
+ u32 tps_srv_ind_lp;
+ u32 tps_srv_ind_hp;
+ u32 cell_id;
+ u32 reason;
+ u32 request_id;
+ u32 modem_state; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
+
+ u32 ber; /* Post Viterbi BER [1E-5] */
+ s32 RSSI; /* dBm */
+ s32 carrier_offset; /* Carrier Offset in bin/1024 */
+
+ u32 is_rf_locked; /* 0 - not locked, 1 - locked */
+ u32 is_demod_locked; /* 0 - not locked, 1 - locked */
+
+ u32 ber_bit_count; /* Total number of SYNC bits. */
+ u32 ber_error_count; /* Number of erroneous SYNC bits. */
+
+ s32 MRC_SNR; /* dB */
+ s32 mrc_in_band_pwr; /* In band power in dBM */
+ s32 MRC_RSSI; /* dBm */
+};
+
+/* From smsdvb-debugfs.c */
+#ifdef CONFIG_SMS_SIANO_DEBUGFS
+
+int smsdvb_debugfs_create(struct smsdvb_client_t *client);
+void smsdvb_debugfs_release(struct smsdvb_client_t *client);
+int smsdvb_debugfs_register(void);
+void smsdvb_debugfs_unregister(void);
+
+#else
+
+static inline int smsdvb_debugfs_create(struct smsdvb_client_t *client)
+{
+ return 0;
+}
+
+static inline void smsdvb_debugfs_release(struct smsdvb_client_t *client) {}
+
+static inline int smsdvb_debugfs_register(void)
+{
+ return 0;
+};
+
+static inline void smsdvb_debugfs_unregister(void) {};
+
+#endif
+
diff --git a/drivers/media/common/siano/smsendian.c b/drivers/media/common/siano/smsendian.c
index e2657c2f010..bfe831c10b1 100644
--- a/drivers/media/common/siano/smsendian.c
+++ b/drivers/media/common/siano/smsendian.c
@@ -28,23 +28,23 @@
void smsendian_handle_tx_message(void *buffer)
{
#ifdef __BIG_ENDIAN
- struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
+ struct sms_msg_data *msg = (struct sms_msg_data *)buffer;
int i;
- int msgWords;
+ int msg_words;
- switch (msg->xMsgHeader.msgType) {
+ switch (msg->x_msg_header.msg_type) {
case MSG_SMS_DATA_DOWNLOAD_REQ:
{
- msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
+ msg->msg_data[0] = le32_to_cpu(msg->msg_data[0]);
break;
}
default:
- msgWords = (msg->xMsgHeader.msgLength -
- sizeof(struct SmsMsgHdr_ST))/4;
+ msg_words = (msg->x_msg_header.msg_length -
+ sizeof(struct sms_msg_hdr))/4;
- for (i = 0; i < msgWords; i++)
- msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
+ for (i = 0; i < msg_words; i++)
+ msg->msg_data[i] = le32_to_cpu(msg->msg_data[i]);
break;
}
@@ -55,16 +55,16 @@ EXPORT_SYMBOL_GPL(smsendian_handle_tx_message);
void smsendian_handle_rx_message(void *buffer)
{
#ifdef __BIG_ENDIAN
- struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
+ struct sms_msg_data *msg = (struct sms_msg_data *)buffer;
int i;
- int msgWords;
+ int msg_words;
- switch (msg->xMsgHeader.msgType) {
+ switch (msg->x_msg_header.msg_type) {
case MSG_SMS_GET_VERSION_EX_RES:
{
- struct SmsVersionRes_ST *ver =
- (struct SmsVersionRes_ST *) msg;
- ver->ChipModel = le16_to_cpu(ver->ChipModel);
+ struct sms_version_res *ver =
+ (struct sms_version_res *) msg;
+ ver->chip_model = le16_to_cpu(ver->chip_model);
break;
}
@@ -77,11 +77,11 @@ void smsendian_handle_rx_message(void *buffer)
default:
{
- msgWords = (msg->xMsgHeader.msgLength -
- sizeof(struct SmsMsgHdr_ST))/4;
+ msg_words = (msg->x_msg_header.msg_length -
+ sizeof(struct sms_msg_hdr))/4;
- for (i = 0; i < msgWords; i++)
- msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
+ for (i = 0; i < msg_words; i++)
+ msg->msg_data[i] = le32_to_cpu(msg->msg_data[i]);
break;
}
@@ -93,11 +93,11 @@ EXPORT_SYMBOL_GPL(smsendian_handle_rx_message);
void smsendian_handle_message_header(void *msg)
{
#ifdef __BIG_ENDIAN
- struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
+ struct sms_msg_hdr *phdr = (struct sms_msg_hdr *)msg;
- phdr->msgType = le16_to_cpu(phdr->msgType);
- phdr->msgLength = le16_to_cpu(phdr->msgLength);
- phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
+ phdr->msg_type = le16_to_cpu(phdr->msg_type);
+ phdr->msg_length = le16_to_cpu(phdr->msg_length);
+ phdr->msg_flags = le16_to_cpu(phdr->msg_flags);
#endif /* __BIG_ENDIAN */
}
EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c
index 37bc5c4b8ad..6d7c0c858bd 100644
--- a/drivers/media/common/siano/smsir.c
+++ b/drivers/media/common/siano/smsir.c
@@ -88,7 +88,7 @@ int sms_ir_init(struct smscore_device_t *coredev)
dev->priv = coredev;
dev->driver_type = RC_DRIVER_IR_RAW;
- dev->allowed_protos = RC_TYPE_ALL;
+ rc_set_allowed_protocols(dev, RC_BIT_ALL);
dev->map_name = sms_get_board(board_id)->rc_codes;
dev->driver_name = MODULE_NAME;
diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h
index ae92b3a8587..fc8b7925c53 100644
--- a/drivers/media/common/siano/smsir.h
+++ b/drivers/media/common/siano/smsir.h
@@ -40,16 +40,24 @@ struct ir_t {
char phys[32];
char *rc_codes;
- u64 protocol;
u32 timeout;
u32 controller;
};
+#ifdef CONFIG_SMS_SIANO_RC
int sms_ir_init(struct smscore_device_t *coredev);
void sms_ir_exit(struct smscore_device_t *coredev);
void sms_ir_event(struct smscore_device_t *coredev,
const char *buf, int len);
+#else
+inline static int sms_ir_init(struct smscore_device_t *coredev) {
+ return 0;
+}
+inline static void sms_ir_exit(struct smscore_device_t *coredev) {};
+inline static void sms_ir_event(struct smscore_device_t *coredev,
+ const char *buf, int len) {};
+#endif
#endif /* __SMS_IR_H__ */
diff --git a/drivers/media/common/tveeprom.c b/drivers/media/common/tveeprom.c
new file mode 100644
index 00000000000..c7dace671a9
--- /dev/null
+++ b/drivers/media/common/tveeprom.c
@@ -0,0 +1,776 @@
+/*
+ * tveeprom - eeprom decoder for tvcard configuration eeproms
+ *
+ * Data and decoding routines shamelessly borrowed from bttv-cards.c
+ * eeprom access routine shamelessly borrowed from bttv-if.c
+ * which are:
+
+ Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
+ & Marcus Metzler (mocm@thp.uni-koeln.de)
+ (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+
+ * Adjustments to fit a more general model and all bugs:
+
+ Copyright (C) 2003 John Klar <linpvr at projectplasma.com>
+
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+
+#include <media/tuner.h>
+#include <media/tveeprom.h>
+#include <media/v4l2-common.h>
+
+MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver");
+MODULE_AUTHOR("John Klar");
+MODULE_LICENSE("GPL");
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+#define STRM(array, i) \
+ (i < sizeof(array) / sizeof(char *) ? array[i] : "unknown")
+
+#define tveeprom_info(fmt, arg...) \
+ v4l_printk(KERN_INFO, "tveeprom", c->adapter, c->addr, fmt , ## arg)
+#define tveeprom_warn(fmt, arg...) \
+ v4l_printk(KERN_WARNING, "tveeprom", c->adapter, c->addr, fmt , ## arg)
+#define tveeprom_dbg(fmt, arg...) do { \
+ if (debug) \
+ v4l_printk(KERN_DEBUG, "tveeprom", \
+ c->adapter, c->addr, fmt , ## arg); \
+ } while (0)
+
+/*
+ * The Hauppauge eeprom uses an 8bit field to determine which
+ * tuner formats the tuner supports.
+ */
+static const struct {
+ int id;
+ const char * const name;
+} hauppauge_tuner_fmt[] = {
+ { V4L2_STD_UNKNOWN, " UNKNOWN" },
+ { V4L2_STD_UNKNOWN, " FM" },
+ { V4L2_STD_B|V4L2_STD_GH, " PAL(B/G)" },
+ { V4L2_STD_MN, " NTSC(M)" },
+ { V4L2_STD_PAL_I, " PAL(I)" },
+ { V4L2_STD_SECAM_L|V4L2_STD_SECAM_LC, " SECAM(L/L')" },
+ { V4L2_STD_DK, " PAL(D/D1/K)" },
+ { V4L2_STD_ATSC, " ATSC/DVB Digital" },
+};
+
+/* This is the full list of possible tuners. Many thanks to Hauppauge for
+ supplying this information. Note that many tuners where only used for
+ testing and never made it to the outside world. So you will only see
+ a subset in actual produced cards. */
+static const struct {
+ int id;
+ const char * const name;
+} hauppauge_tuner[] = {
+ /* 0-9 */
+ { TUNER_ABSENT, "None" },
+ { TUNER_ABSENT, "External" },
+ { TUNER_ABSENT, "Unspecified" },
+ { TUNER_PHILIPS_PAL, "Philips FI1216" },
+ { TUNER_PHILIPS_SECAM, "Philips FI1216MF" },
+ { TUNER_PHILIPS_NTSC, "Philips FI1236" },
+ { TUNER_PHILIPS_PAL_I, "Philips FI1246" },
+ { TUNER_PHILIPS_PAL_DK, "Philips FI1256" },
+ { TUNER_PHILIPS_PAL, "Philips FI1216 MK2" },
+ { TUNER_PHILIPS_SECAM, "Philips FI1216MF MK2" },
+ /* 10-19 */
+ { TUNER_PHILIPS_NTSC, "Philips FI1236 MK2" },
+ { TUNER_PHILIPS_PAL_I, "Philips FI1246 MK2" },
+ { TUNER_PHILIPS_PAL_DK, "Philips FI1256 MK2" },
+ { TUNER_TEMIC_NTSC, "Temic 4032FY5" },
+ { TUNER_TEMIC_PAL, "Temic 4002FH5" },
+ { TUNER_TEMIC_PAL_I, "Temic 4062FY5" },
+ { TUNER_PHILIPS_PAL, "Philips FR1216 MK2" },
+ { TUNER_PHILIPS_SECAM, "Philips FR1216MF MK2" },
+ { TUNER_PHILIPS_NTSC, "Philips FR1236 MK2" },
+ { TUNER_PHILIPS_PAL_I, "Philips FR1246 MK2" },
+ /* 20-29 */
+ { TUNER_PHILIPS_PAL_DK, "Philips FR1256 MK2" },
+ { TUNER_PHILIPS_PAL, "Philips FM1216" },
+ { TUNER_PHILIPS_SECAM, "Philips FM1216MF" },
+ { TUNER_PHILIPS_NTSC, "Philips FM1236" },
+ { TUNER_PHILIPS_PAL_I, "Philips FM1246" },
+ { TUNER_PHILIPS_PAL_DK, "Philips FM1256" },
+ { TUNER_TEMIC_4036FY5_NTSC, "Temic 4036FY5" },
+ { TUNER_ABSENT, "Samsung TCPN9082D" },
+ { TUNER_ABSENT, "Samsung TCPM9092P" },
+ { TUNER_TEMIC_4006FH5_PAL, "Temic 4006FH5" },
+ /* 30-39 */
+ { TUNER_ABSENT, "Samsung TCPN9085D" },
+ { TUNER_ABSENT, "Samsung TCPB9085P" },
+ { TUNER_ABSENT, "Samsung TCPL9091P" },
+ { TUNER_TEMIC_4039FR5_NTSC, "Temic 4039FR5" },
+ { TUNER_PHILIPS_FQ1216ME, "Philips FQ1216 ME" },
+ { TUNER_TEMIC_4066FY5_PAL_I, "Temic 4066FY5" },
+ { TUNER_PHILIPS_NTSC, "Philips TD1536" },
+ { TUNER_PHILIPS_NTSC, "Philips TD1536D" },
+ { TUNER_PHILIPS_NTSC, "Philips FMR1236" }, /* mono radio */
+ { TUNER_ABSENT, "Philips FI1256MP" },
+ /* 40-49 */
+ { TUNER_ABSENT, "Samsung TCPQ9091P" },
+ { TUNER_TEMIC_4006FN5_MULTI_PAL,"Temic 4006FN5" },
+ { TUNER_TEMIC_4009FR5_PAL, "Temic 4009FR5" },
+ { TUNER_TEMIC_4046FM5, "Temic 4046FM5" },
+ { TUNER_TEMIC_4009FN5_MULTI_PAL_FM, "Temic 4009FN5" },
+ { TUNER_ABSENT, "Philips TD1536D FH 44"},
+ { TUNER_LG_NTSC_FM, "LG TP18NSR01F"},
+ { TUNER_LG_PAL_FM, "LG TP18PSB01D"},
+ { TUNER_LG_PAL, "LG TP18PSB11D"},
+ { TUNER_LG_PAL_I_FM, "LG TAPC-I001D"},
+ /* 50-59 */
+ { TUNER_LG_PAL_I, "LG TAPC-I701D"},
+ { TUNER_ABSENT, "Temic 4042FI5"},
+ { TUNER_MICROTUNE_4049FM5, "Microtune 4049 FM5"},
+ { TUNER_ABSENT, "LG TPI8NSR11F"},
+ { TUNER_ABSENT, "Microtune 4049 FM5 Alt I2C"},
+ { TUNER_PHILIPS_FM1216ME_MK3, "Philips FQ1216ME MK3"},
+ { TUNER_ABSENT, "Philips FI1236 MK3"},
+ { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216 ME MK3"},
+ { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK3"},
+ { TUNER_ABSENT, "Philips FM1216MP MK3"},
+ /* 60-69 */
+ { TUNER_PHILIPS_FM1216ME_MK3, "LG S001D MK3"},
+ { TUNER_ABSENT, "LG M001D MK3"},
+ { TUNER_PHILIPS_FM1216ME_MK3, "LG S701D MK3"},
+ { TUNER_ABSENT, "LG M701D MK3"},
+ { TUNER_ABSENT, "Temic 4146FM5"},
+ { TUNER_ABSENT, "Temic 4136FY5"},
+ { TUNER_ABSENT, "Temic 4106FH5"},
+ { TUNER_ABSENT, "Philips FQ1216LMP MK3"},
+ { TUNER_LG_NTSC_TAPE, "LG TAPE H001F MK3"},
+ { TUNER_LG_NTSC_TAPE, "LG TAPE H701F MK3"},
+ /* 70-79 */
+ { TUNER_ABSENT, "LG TALN H200T"},
+ { TUNER_ABSENT, "LG TALN H250T"},
+ { TUNER_ABSENT, "LG TALN M200T"},
+ { TUNER_ABSENT, "LG TALN Z200T"},
+ { TUNER_ABSENT, "LG TALN S200T"},
+ { TUNER_ABSENT, "Thompson DTT7595"},
+ { TUNER_ABSENT, "Thompson DTT7592"},
+ { TUNER_ABSENT, "Silicon TDA8275C1 8290"},
+ { TUNER_ABSENT, "Silicon TDA8275C1 8290 FM"},
+ { TUNER_ABSENT, "Thompson DTT757"},
+ /* 80-89 */
+ { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK3"},
+ { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"},
+ { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
+ { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
+ { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
+ { TUNER_TCL_2002N, "TCL 2002N 6A"},
+ { TUNER_PHILIPS_FM1236_MK3, "Philips FQ1236 MK3"},
+ { TUNER_SAMSUNG_TCPN_2121P30A, "Samsung TCPN 2121P30A"},
+ { TUNER_ABSENT, "Samsung TCPE 4121P30A"},
+ { TUNER_PHILIPS_FM1216ME_MK3, "TCL MFPE05 2"},
+ /* 90-99 */
+ { TUNER_ABSENT, "LG TALN H202T"},
+ { TUNER_PHILIPS_FQ1216AME_MK4, "Philips FQ1216AME MK4"},
+ { TUNER_PHILIPS_FQ1236A_MK4, "Philips FQ1236A MK4"},
+ { TUNER_ABSENT, "Philips FQ1286A MK4"},
+ { TUNER_ABSENT, "Philips FQ1216ME MK5"},
+ { TUNER_ABSENT, "Philips FQ1236 MK5"},
+ { TUNER_SAMSUNG_TCPG_6121P30A, "Samsung TCPG 6121P30A"},
+ { TUNER_TCL_2002MB, "TCL 2002MB_3H"},
+ { TUNER_ABSENT, "TCL 2002MI_3H"},
+ { TUNER_TCL_2002N, "TCL 2002N 5H"},
+ /* 100-109 */
+ { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216ME"},
+ { TUNER_TEA5767, "Philips TEA5768HL FM Radio"},
+ { TUNER_ABSENT, "Panasonic ENV57H12D5"},
+ { TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"},
+ { TUNER_PHILIPS_FM1236_MK3, "TCL MNM05-4"},
+ { TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
+ { TUNER_ABSENT, "TCL MQNM05-4"},
+ { TUNER_ABSENT, "LG TAPC-W701D"},
+ { TUNER_ABSENT, "TCL 9886P-WM"},
+ { TUNER_ABSENT, "TCL 1676NM-WM"},
+ /* 110-119 */
+ { TUNER_ABSENT, "Thompson DTT75105"},
+ { TUNER_ABSENT, "Conexant_CX24109"},
+ { TUNER_TCL_2002N, "TCL M2523_5N_E"},
+ { TUNER_TCL_2002MB, "TCL M2523_3DB_E"},
+ { TUNER_ABSENT, "Philips 8275A"},
+ { TUNER_ABSENT, "Microtune MT2060"},
+ { TUNER_PHILIPS_FM1236_MK3, "Philips FM1236 MK5"},
+ { TUNER_PHILIPS_FM1216ME_MK3, "Philips FM1216ME MK5"},
+ { TUNER_ABSENT, "TCL M2523_3DI_E"},
+ { TUNER_ABSENT, "Samsung THPD5222FG30A"},
+ /* 120-129 */
+ { TUNER_XC2028, "Xceive XC3028"},
+ { TUNER_PHILIPS_FQ1216LME_MK3, "Philips FQ1216LME MK5"},
+ { TUNER_ABSENT, "Philips FQD1216LME"},
+ { TUNER_ABSENT, "Conexant CX24118A"},
+ { TUNER_ABSENT, "TCL DMF11WIP"},
+ { TUNER_ABSENT, "TCL MFNM05_4H_E"},
+ { TUNER_ABSENT, "TCL MNM05_4H_E"},
+ { TUNER_ABSENT, "TCL MPE05_2H_E"},
+ { TUNER_ABSENT, "TCL MQNM05_4_U"},
+ { TUNER_ABSENT, "TCL M2523_5NH_E"},
+ /* 130-139 */
+ { TUNER_ABSENT, "TCL M2523_3DBH_E"},
+ { TUNER_ABSENT, "TCL M2523_3DIH_E"},
+ { TUNER_ABSENT, "TCL MFPE05_2_U"},
+ { TUNER_PHILIPS_FMD1216MEX_MK3, "Philips FMD1216MEX"},
+ { TUNER_ABSENT, "Philips FRH2036B"},
+ { TUNER_ABSENT, "Panasonic ENGF75_01GF"},
+ { TUNER_ABSENT, "MaxLinear MXL5005"},
+ { TUNER_ABSENT, "MaxLinear MXL5003"},
+ { TUNER_ABSENT, "Xceive XC2028"},
+ { TUNER_ABSENT, "Microtune MT2131"},
+ /* 140-149 */
+ { TUNER_ABSENT, "Philips 8275A_8295"},
+ { TUNER_ABSENT, "TCL MF02GIP_5N_E"},
+ { TUNER_ABSENT, "TCL MF02GIP_3DB_E"},
+ { TUNER_ABSENT, "TCL MF02GIP_3DI_E"},
+ { TUNER_ABSENT, "Microtune MT2266"},
+ { TUNER_ABSENT, "TCL MF10WPP_4N_E"},
+ { TUNER_ABSENT, "LG TAPQ_H702F"},
+ { TUNER_ABSENT, "TCL M09WPP_4N_E"},
+ { TUNER_ABSENT, "MaxLinear MXL5005_v2"},
+ { TUNER_PHILIPS_TDA8290, "Philips 18271_8295"},
+ /* 150-159 */
+ { TUNER_XC5000, "Xceive XC5000"},
+ { TUNER_ABSENT, "Xceive XC3028L"},
+ { TUNER_ABSENT, "NXP 18271C2_716x"},
+ { TUNER_ABSENT, "Xceive XC4000"},
+ { TUNER_ABSENT, "Dibcom 7070"},
+ { TUNER_PHILIPS_TDA8290, "NXP 18271C2"},
+ { TUNER_ABSENT, "Siano SMS1010"},
+ { TUNER_ABSENT, "Siano SMS1150"},
+ { TUNER_ABSENT, "MaxLinear 5007"},
+ { TUNER_ABSENT, "TCL M09WPP_2P_E"},
+ /* 160-169 */
+ { TUNER_ABSENT, "Siano SMS1180"},
+ { TUNER_ABSENT, "Maxim_MAX2165"},
+ { TUNER_ABSENT, "Siano SMS1140"},
+ { TUNER_ABSENT, "Siano SMS1150 B1"},
+ { TUNER_ABSENT, "MaxLinear 111"},
+ { TUNER_ABSENT, "Dibcom 7770"},
+ { TUNER_ABSENT, "Siano SMS1180VNS"},
+ { TUNER_ABSENT, "Siano SMS1184"},
+ { TUNER_PHILIPS_FQ1236_MK5, "TCL M30WTP-4N-E"},
+ { TUNER_ABSENT, "TCL_M11WPP_2PN_E"},
+ /* 170-179 */
+ { TUNER_ABSENT, "MaxLinear 301"},
+ { TUNER_ABSENT, "Mirics MSi001"},
+ { TUNER_ABSENT, "MaxLinear MxL241SF"},
+ { TUNER_XC5000C, "Xceive XC5000C"},
+ { TUNER_ABSENT, "Montage M68TS2020"},
+ { TUNER_ABSENT, "Siano SMS1530"},
+ { TUNER_ABSENT, "Dibcom 7090"},
+ { TUNER_ABSENT, "Xceive XC5200C"},
+ { TUNER_ABSENT, "NXP 18273"},
+ { TUNER_ABSENT, "Montage M88TS2022"},
+ /* 180-189 */
+ { TUNER_ABSENT, "NXP 18272M"},
+ { TUNER_ABSENT, "NXP 18272S"},
+};
+
+/* Use TVEEPROM_AUDPROC_INTERNAL for those audio 'chips' that are
+ * internal to a video chip, i.e. not a separate audio chip. */
+static const struct {
+ u32 id;
+ const char * const name;
+} audio_ic[] = {
+ /* 0-4 */
+ { TVEEPROM_AUDPROC_NONE, "None" },
+ { TVEEPROM_AUDPROC_OTHER, "TEA6300" },
+ { TVEEPROM_AUDPROC_OTHER, "TEA6320" },
+ { TVEEPROM_AUDPROC_OTHER, "TDA9850" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3400C" },
+ /* 5-9 */
+ { TVEEPROM_AUDPROC_MSP, "MSP3410D" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3415" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3430" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3438" },
+ { TVEEPROM_AUDPROC_OTHER, "CS5331" },
+ /* 10-14 */
+ { TVEEPROM_AUDPROC_MSP, "MSP3435" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3440" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3445" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3411" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3416" },
+ /* 15-19 */
+ { TVEEPROM_AUDPROC_MSP, "MSP3425" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3451" },
+ { TVEEPROM_AUDPROC_MSP, "MSP3418" },
+ { TVEEPROM_AUDPROC_OTHER, "Type 0x12" },
+ { TVEEPROM_AUDPROC_OTHER, "OKI7716" },
+ /* 20-24 */
+ { TVEEPROM_AUDPROC_MSP, "MSP4410" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4420" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4440" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4450" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4408" },
+ /* 25-29 */
+ { TVEEPROM_AUDPROC_MSP, "MSP4418" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4428" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4448" },
+ { TVEEPROM_AUDPROC_MSP, "MSP4458" },
+ { TVEEPROM_AUDPROC_MSP, "Type 0x1d" },
+ /* 30-34 */
+ { TVEEPROM_AUDPROC_INTERNAL, "CX880" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX881" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX883" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX882" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX25840" },
+ /* 35-39 */
+ { TVEEPROM_AUDPROC_INTERNAL, "CX25841" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX25842" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX25843" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX23418" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX23885" },
+ /* 40-44 */
+ { TVEEPROM_AUDPROC_INTERNAL, "CX23888" },
+ { TVEEPROM_AUDPROC_INTERNAL, "SAA7131" },
+ { TVEEPROM_AUDPROC_INTERNAL, "CX23887" },
+ { TVEEPROM_AUDPROC_INTERNAL, "SAA7164" },
+ { TVEEPROM_AUDPROC_INTERNAL, "AU8522" },
+};
+
+/* This list is supplied by Hauppauge. Thanks! */
+static const char *decoderIC[] = {
+ /* 0-4 */
+ "None", "BT815", "BT817", "BT819", "BT815A",
+ /* 5-9 */
+ "BT817A", "BT819A", "BT827", "BT829", "BT848",
+ /* 10-14 */
+ "BT848A", "BT849A", "BT829A", "BT827A", "BT878",
+ /* 15-19 */
+ "BT879", "BT880", "VPX3226E", "SAA7114", "SAA7115",
+ /* 20-24 */
+ "CX880", "CX881", "CX883", "SAA7111", "SAA7113",
+ /* 25-29 */
+ "CX882", "TVP5150A", "CX25840", "CX25841", "CX25842",
+ /* 30-34 */
+ "CX25843", "CX23418", "NEC61153", "CX23885", "CX23888",
+ /* 35-39 */
+ "SAA7131", "CX25837", "CX23887", "CX23885A", "CX23887A",
+ /* 40-42 */
+ "SAA7164", "CX23885B", "AU8522"
+};
+
+static int hasRadioTuner(int tunerType)
+{
+ switch (tunerType) {
+ case 18: /* PNPEnv_TUNER_FR1236_MK2 */
+ case 23: /* PNPEnv_TUNER_FM1236 */
+ case 38: /* PNPEnv_TUNER_FMR1236 */
+ case 16: /* PNPEnv_TUNER_FR1216_MK2 */
+ case 19: /* PNPEnv_TUNER_FR1246_MK2 */
+ case 21: /* PNPEnv_TUNER_FM1216 */
+ case 24: /* PNPEnv_TUNER_FM1246 */
+ case 17: /* PNPEnv_TUNER_FR1216MF_MK2 */
+ case 22: /* PNPEnv_TUNER_FM1216MF */
+ case 20: /* PNPEnv_TUNER_FR1256_MK2 */
+ case 25: /* PNPEnv_TUNER_FM1256 */
+ case 33: /* PNPEnv_TUNER_4039FR5 */
+ case 42: /* PNPEnv_TUNER_4009FR5 */
+ case 52: /* PNPEnv_TUNER_4049FM5 */
+ case 54: /* PNPEnv_TUNER_4049FM5_AltI2C */
+ case 44: /* PNPEnv_TUNER_4009FN5 */
+ case 31: /* PNPEnv_TUNER_TCPB9085P */
+ case 30: /* PNPEnv_TUNER_TCPN9085D */
+ case 46: /* PNPEnv_TUNER_TP18NSR01F */
+ case 47: /* PNPEnv_TUNER_TP18PSB01D */
+ case 49: /* PNPEnv_TUNER_TAPC_I001D */
+ case 60: /* PNPEnv_TUNER_TAPE_S001D_MK3 */
+ case 57: /* PNPEnv_TUNER_FM1216ME_MK3 */
+ case 59: /* PNPEnv_TUNER_FM1216MP_MK3 */
+ case 58: /* PNPEnv_TUNER_FM1236_MK3 */
+ case 68: /* PNPEnv_TUNER_TAPE_H001F_MK3 */
+ case 61: /* PNPEnv_TUNER_TAPE_M001D_MK3 */
+ case 78: /* PNPEnv_TUNER_TDA8275C1_8290_FM */
+ case 89: /* PNPEnv_TUNER_TCL_MFPE05_2 */
+ case 92: /* PNPEnv_TUNER_PHILIPS_FQ1236A_MK4 */
+ case 105:
+ return 1;
+ }
+ return 0;
+}
+
+void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
+ unsigned char *eeprom_data)
+{
+ /* ----------------------------------------------
+ ** The hauppauge eeprom format is tagged
+ **
+ ** if packet[0] == 0x84, then packet[0..1] == length
+ ** else length = packet[0] & 3f;
+ ** if packet[0] & f8 == f8, then EOD and packet[1] == checksum
+ **
+ ** In our (ivtv) case we're interested in the following:
+ ** tuner type: tag [00].05 or [0a].01 (index into hauppauge_tuner)
+ ** tuner fmts: tag [00].04 or [0a].00 (bitmask index into
+ ** hauppauge_tuner_fmt)
+ ** radio: tag [00].{last} or [0e].00 (bitmask. bit2=FM)
+ ** audio proc: tag [02].01 or [05].00 (mask with 0x7f)
+ ** decoder proc: tag [09].01)
+
+ ** Fun info:
+ ** model: tag [00].07-08 or [06].00-01
+ ** revision: tag [00].09-0b or [06].04-06
+ ** serial#: tag [01].05-07 or [04].04-06
+
+ ** # of inputs/outputs ???
+ */
+
+ int i, j, len, done, beenhere, tag, start;
+
+ int tuner1 = 0, t_format1 = 0, audioic = -1;
+ const char *t_name1 = NULL;
+ const char *t_fmt_name1[8] = { " none", "", "", "", "", "", "", "" };
+
+ int tuner2 = 0, t_format2 = 0;
+ const char *t_name2 = NULL;
+ const char *t_fmt_name2[8] = { " none", "", "", "", "", "", "", "" };
+
+ memset(tvee, 0, sizeof(*tvee));
+ tvee->tuner_type = TUNER_ABSENT;
+ tvee->tuner2_type = TUNER_ABSENT;
+
+ done = len = beenhere = 0;
+
+ /* Different eeprom start offsets for em28xx, cx2388x and cx23418 */
+ if (eeprom_data[0] == 0x1a &&
+ eeprom_data[1] == 0xeb &&
+ eeprom_data[2] == 0x67 &&
+ eeprom_data[3] == 0x95)
+ start = 0xa0; /* Generic em28xx offset */
+ else if ((eeprom_data[0] & 0xe1) == 0x01 &&
+ eeprom_data[1] == 0x00 &&
+ eeprom_data[2] == 0x00 &&
+ eeprom_data[8] == 0x84)
+ start = 8; /* Generic cx2388x offset */
+ else if (eeprom_data[1] == 0x70 &&
+ eeprom_data[2] == 0x00 &&
+ eeprom_data[4] == 0x74 &&
+ eeprom_data[8] == 0x84)
+ start = 8; /* Generic cx23418 offset (models 74xxx) */
+ else
+ start = 0;
+
+ for (i = start; !done && i < 256; i += len) {
+ if (eeprom_data[i] == 0x84) {
+ len = eeprom_data[i + 1] + (eeprom_data[i + 2] << 8);
+ i += 3;
+ } else if ((eeprom_data[i] & 0xf0) == 0x70) {
+ if (eeprom_data[i] & 0x08) {
+ /* verify checksum! */
+ done = 1;
+ break;
+ }
+ len = eeprom_data[i] & 0x07;
+ ++i;
+ } else {
+ tveeprom_warn("Encountered bad packet header [%02x]. "
+ "Corrupt or not a Hauppauge eeprom.\n",
+ eeprom_data[i]);
+ return;
+ }
+
+ if (debug) {
+ tveeprom_info("Tag [%02x] + %d bytes:",
+ eeprom_data[i], len - 1);
+ for (j = 1; j < len; j++)
+ printk(KERN_CONT " %02x", eeprom_data[i + j]);
+ printk(KERN_CONT "\n");
+ }
+
+ /* process by tag */
+ tag = eeprom_data[i];
+ switch (tag) {
+ case 0x00:
+ /* tag: 'Comprehensive' */
+ tuner1 = eeprom_data[i+6];
+ t_format1 = eeprom_data[i+5];
+ tvee->has_radio = eeprom_data[i+len-1];
+ /* old style tag, don't know how to detect
+ IR presence, mark as unknown. */
+ tvee->has_ir = 0;
+ tvee->model =
+ eeprom_data[i+8] +
+ (eeprom_data[i+9] << 8);
+ tvee->revision = eeprom_data[i+10] +
+ (eeprom_data[i+11] << 8) +
+ (eeprom_data[i+12] << 16);
+ break;
+
+ case 0x01:
+ /* tag: 'SerialID' */
+ tvee->serial_number =
+ eeprom_data[i+6] +
+ (eeprom_data[i+7] << 8) +
+ (eeprom_data[i+8] << 16);
+ break;
+
+ case 0x02:
+ /* tag 'AudioInfo'
+ Note mask with 0x7F, high bit used on some older models
+ to indicate 4052 mux was removed in favor of using MSP
+ inputs directly. */
+ audioic = eeprom_data[i+2] & 0x7f;
+ if (audioic < ARRAY_SIZE(audio_ic))
+ tvee->audio_processor = audio_ic[audioic].id;
+ else
+ tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
+ break;
+
+ /* case 0x03: tag 'EEInfo' */
+
+ case 0x04:
+ /* tag 'SerialID2' */
+ tvee->serial_number =
+ eeprom_data[i+5] +
+ (eeprom_data[i+6] << 8) +
+ (eeprom_data[i+7] << 16);
+
+ if ((eeprom_data[i + 8] & 0xf0) &&
+ (tvee->serial_number < 0xffffff)) {
+ tvee->MAC_address[0] = 0x00;
+ tvee->MAC_address[1] = 0x0D;
+ tvee->MAC_address[2] = 0xFE;
+ tvee->MAC_address[3] = eeprom_data[i + 7];
+ tvee->MAC_address[4] = eeprom_data[i + 6];
+ tvee->MAC_address[5] = eeprom_data[i + 5];
+ tvee->has_MAC_address = 1;
+ }
+ break;
+
+ case 0x05:
+ /* tag 'Audio2'
+ Note mask with 0x7F, high bit used on some older models
+ to indicate 4052 mux was removed in favor of using MSP
+ inputs directly. */
+ audioic = eeprom_data[i+1] & 0x7f;
+ if (audioic < ARRAY_SIZE(audio_ic))
+ tvee->audio_processor = audio_ic[audioic].id;
+ else
+ tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
+
+ break;
+
+ case 0x06:
+ /* tag 'ModelRev' */
+ tvee->model =
+ eeprom_data[i + 1] +
+ (eeprom_data[i + 2] << 8) +
+ (eeprom_data[i + 3] << 16) +
+ (eeprom_data[i + 4] << 24);
+ tvee->revision =
+ eeprom_data[i + 5] +
+ (eeprom_data[i + 6] << 8) +
+ (eeprom_data[i + 7] << 16);
+ break;
+
+ case 0x07:
+ /* tag 'Details': according to Hauppauge not interesting
+ on any PCI-era or later boards. */
+ break;
+
+ /* there is no tag 0x08 defined */
+
+ case 0x09:
+ /* tag 'Video' */
+ tvee->decoder_processor = eeprom_data[i + 1];
+ break;
+
+ case 0x0a:
+ /* tag 'Tuner' */
+ if (beenhere == 0) {
+ tuner1 = eeprom_data[i + 2];
+ t_format1 = eeprom_data[i + 1];
+ beenhere = 1;
+ } else {
+ /* a second (radio) tuner may be present */
+ tuner2 = eeprom_data[i + 2];
+ t_format2 = eeprom_data[i + 1];
+ /* not a TV tuner? */
+ if (t_format2 == 0)
+ tvee->has_radio = 1; /* must be radio */
+ }
+ break;
+
+ case 0x0b:
+ /* tag 'Inputs': according to Hauppauge this is specific
+ to each driver family, so no good assumptions can be
+ made. */
+ break;
+
+ /* case 0x0c: tag 'Balun' */
+ /* case 0x0d: tag 'Teletext' */
+
+ case 0x0e:
+ /* tag: 'Radio' */
+ tvee->has_radio = eeprom_data[i+1];
+ break;
+
+ case 0x0f:
+ /* tag 'IRInfo' */
+ tvee->has_ir = 1 | (eeprom_data[i+1] << 1);
+ break;
+
+ /* case 0x10: tag 'VBIInfo' */
+ /* case 0x11: tag 'QCInfo' */
+ /* case 0x12: tag 'InfoBits' */
+
+ default:
+ tveeprom_dbg("Not sure what to do with tag [%02x]\n",
+ tag);
+ /* dump the rest of the packet? */
+ }
+ }
+
+ if (!done) {
+ tveeprom_warn("Ran out of data!\n");
+ return;
+ }
+
+ if (tvee->revision != 0) {
+ tvee->rev_str[0] = 32 + ((tvee->revision >> 18) & 0x3f);
+ tvee->rev_str[1] = 32 + ((tvee->revision >> 12) & 0x3f);
+ tvee->rev_str[2] = 32 + ((tvee->revision >> 6) & 0x3f);
+ tvee->rev_str[3] = 32 + (tvee->revision & 0x3f);
+ tvee->rev_str[4] = 0;
+ }
+
+ if (hasRadioTuner(tuner1) && !tvee->has_radio) {
+ tveeprom_info("The eeprom says no radio is present, but the tuner type\n");
+ tveeprom_info("indicates otherwise. I will assume that radio is present.\n");
+ tvee->has_radio = 1;
+ }
+
+ if (tuner1 < ARRAY_SIZE(hauppauge_tuner)) {
+ tvee->tuner_type = hauppauge_tuner[tuner1].id;
+ t_name1 = hauppauge_tuner[tuner1].name;
+ } else {
+ t_name1 = "unknown";
+ }
+
+ if (tuner2 < ARRAY_SIZE(hauppauge_tuner)) {
+ tvee->tuner2_type = hauppauge_tuner[tuner2].id;
+ t_name2 = hauppauge_tuner[tuner2].name;
+ } else {
+ t_name2 = "unknown";
+ }
+
+ tvee->tuner_hauppauge_model = tuner1;
+ tvee->tuner2_hauppauge_model = tuner2;
+ tvee->tuner_formats = 0;
+ tvee->tuner2_formats = 0;
+ for (i = j = 0; i < 8; i++) {
+ if (t_format1 & (1 << i)) {
+ tvee->tuner_formats |= hauppauge_tuner_fmt[i].id;
+ t_fmt_name1[j++] = hauppauge_tuner_fmt[i].name;
+ }
+ }
+ for (i = j = 0; i < 8; i++) {
+ if (t_format2 & (1 << i)) {
+ tvee->tuner2_formats |= hauppauge_tuner_fmt[i].id;
+ t_fmt_name2[j++] = hauppauge_tuner_fmt[i].name;
+ }
+ }
+
+ tveeprom_info("Hauppauge model %d, rev %s, serial# %d\n",
+ tvee->model, tvee->rev_str, tvee->serial_number);
+ if (tvee->has_MAC_address == 1)
+ tveeprom_info("MAC address is %pM\n", tvee->MAC_address);
+ tveeprom_info("tuner model is %s (idx %d, type %d)\n",
+ t_name1, tuner1, tvee->tuner_type);
+ tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
+ t_fmt_name1[0], t_fmt_name1[1], t_fmt_name1[2],
+ t_fmt_name1[3], t_fmt_name1[4], t_fmt_name1[5],
+ t_fmt_name1[6], t_fmt_name1[7], t_format1);
+ if (tuner2)
+ tveeprom_info("second tuner model is %s (idx %d, type %d)\n",
+ t_name2, tuner2, tvee->tuner2_type);
+ if (t_format2)
+ tveeprom_info("TV standards%s%s%s%s%s%s%s%s (eeprom 0x%02x)\n",
+ t_fmt_name2[0], t_fmt_name2[1], t_fmt_name2[2],
+ t_fmt_name2[3], t_fmt_name2[4], t_fmt_name2[5],
+ t_fmt_name2[6], t_fmt_name2[7], t_format2);
+ if (audioic < 0) {
+ tveeprom_info("audio processor is unknown (no idx)\n");
+ tvee->audio_processor = TVEEPROM_AUDPROC_OTHER;
+ } else {
+ if (audioic < ARRAY_SIZE(audio_ic))
+ tveeprom_info("audio processor is %s (idx %d)\n",
+ audio_ic[audioic].name, audioic);
+ else
+ tveeprom_info("audio processor is unknown (idx %d)\n",
+ audioic);
+ }
+ if (tvee->decoder_processor)
+ tveeprom_info("decoder processor is %s (idx %d)\n",
+ STRM(decoderIC, tvee->decoder_processor),
+ tvee->decoder_processor);
+ if (tvee->has_ir)
+ tveeprom_info("has %sradio, has %sIR receiver, has %sIR transmitter\n",
+ tvee->has_radio ? "" : "no ",
+ (tvee->has_ir & 2) ? "" : "no ",
+ (tvee->has_ir & 4) ? "" : "no ");
+ else
+ tveeprom_info("has %sradio\n",
+ tvee->has_radio ? "" : "no ");
+}
+EXPORT_SYMBOL(tveeprom_hauppauge_analog);
+
+/* ----------------------------------------------------------------------- */
+/* generic helper functions */
+
+int tveeprom_read(struct i2c_client *c, unsigned char *eedata, int len)
+{
+ unsigned char buf;
+ int err;
+
+ buf = 0;
+ err = i2c_master_send(c, &buf, 1);
+ if (err != 1) {
+ tveeprom_info("Huh, no eeprom present (err=%d)?\n", err);
+ return -1;
+ }
+ err = i2c_master_recv(c, eedata, len);
+ if (err != len) {
+ tveeprom_warn("i2c eeprom read error (err=%d)\n", err);
+ return -1;
+ }
+ if (debug) {
+ int i;
+
+ tveeprom_info("full 256-byte eeprom dump:\n");
+ for (i = 0; i < len; i++) {
+ if (0 == (i % 16))
+ tveeprom_info("%02x:", i);
+ printk(KERN_CONT " %02x", eedata[i]);
+ if (15 == (i % 16))
+ printk(KERN_CONT "\n");
+ }
+ }
+ return 0;
+}
+EXPORT_SYMBOL(tveeprom_read);