[PATCH v3 1/1] [stage/sunxi-3.4] Add support for Allwinner (DVB/ATSC) Transport Stream Controller(s) (TSC)

713 views
Skip to first unread message

thomas schorpp

unread,
Aug 9, 2013, 12:23:13 PM8/9/13
to linux...@googlegroups.com
Please report boards and AW SoC types with TS0 AND TS1 inputs available and in which GPIO multiplex mode.

I'm modifying script for CSI -> TS now and test init of the driver built in kernel.

Signed-off-by: Thomas Schorpp <thomas....@gmail.com>

---

diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index f6e40b3..19de663 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -84,6 +84,10 @@ comment "Supported ddbridge ('Octopus') Adapters"
depends on DVB_CORE && PCI && I2C
source "drivers/media/dvb/ddbridge/Kconfig"

+comment "Supported SoC TS Capture Controllers"
+ depends on DVB_CORE
+ source "drivers/media/dvb/soc/Kconfig"
+
comment "Supported DVB Frontends"
depends on DVB_CORE
source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index b2cefe6..053abd3 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -16,6 +16,7 @@ obj-y := dvb-core/ \
pt1/ \
mantis/ \
ngene/ \
- ddbridge/
+ ddbridge/ \
+ soc/

obj-$(CONFIG_DVB_FIREDTV) += firewire/
diff --git a/drivers/media/dvb/soc/Kconfig b/drivers/media/dvb/soc/Kconfig
new file mode 100644
index 0000000..d795da3
--- /dev/null
+++ b/drivers/media/dvb/soc/Kconfig
@@ -0,0 +1,60 @@
+# TODO:
+# 1. Selective TS- Ports/Controller(s?) config, auto-disable CSI drivers in Kconfig.
+# 2. Auto- Select tuner pll/sec/lnb drivers,
+# but there may be modules around with other/unsupported PLL- chips,
+# so let user choose them.
+# 3. Support for DVB-S2/T2/C2/ATSC(?) receivers (Me not before SDTV gets off the air.)
+# 4. CI+ CA Support (In Your dreams).
+
+config DVB_TSC_SUNXI
+ bool "TS Controller Driver for Allwinner A10/A20 TSC"
+ default n
+ depends on DVB_CORE && PLAT_SUNXI
+
+if DVB_TSC_SUNXI
+
+config TS0_SUN4I
+ tristate "TS0 TS capture & demux input for sun4i/5i/7i, A10/A13/A20"
+ default n
+# depends on ARCH_SUN4I || ARCH_SUN5I || ARCH_SUN7I
+ select VIDEOBUF_DMA_CONTIG
+
+config TS1_SUN7I
+ tristate "TS1 TS capture & demux input for sun7i/sunxi, A20"
+ default n
+# depends on ARCH_SUN7I
+ select VIDEOBUF_DMA_CONTIG
+
+menu "Supported attached DVB/ATSC Receiver modules"
+
+config TSC_CU1216
+ tristate "Philips CU1216 DVB-C Receiver"
+ depends on I2C && DVB_FE_CUSTOMISE
+ select DVB_TDA10021
+ ---help---
+ I2C/TS Philips CU1216 and Clones TDA10021 based DVB-C Receiver Module
+
+config TSC_CU1216_MKIII
+ tristate "Philips CU1216-MKIII DVB-C Receiver"
+ depends on I2C && DVB_FE_CUSTOMISE
+ select DVB_TDA10023
+ ---help---
+ I2C/TS Philips CU1216-MKIII and Clones TDA10023 based DVB-C Receiver Module
+
+config TSC_SHARP_BS2F7_Z0_95
+ tristate "Sharp BS2F7(V/H)Z0(2/3)95 DVB-S Receiver"
+ depends on I2C && DVB_FE_CUSTOMISE
+ select DVB_STV0288
+ ---help---
+ I2C/TS Sharp BS2F7(V/H)Z0(2/3)95 STV0288 DVB-S Receiver Module
+
+config TSC_BSBE1
+ tristate "BSBE1 DVB-C -Receiver"
+ depends on I2C && DVB_FE_CUSTOMISE
+ select DVB_STV0299
+ ---help---
+ I2C/TS "BSBE1-502A" DVB-S Receiver Extensions Module (Found on TT FF/HPE Nexus dvb-s pci)
+
+endmenu
+endif
+
diff --git a/drivers/media/dvb/soc/Makefile b/drivers/media/dvb/soc/Makefile
new file mode 100644
index 0000000..1cbaedc
--- /dev/null
+++ b/drivers/media/dvb/soc/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_TS0_SUN4I) += tscdrv.o
+#obj-$(CONFIG_TS1_SUN7I) += tscdrv.o
+
diff --git a/drivers/media/dvb/soc/dvb_drv_sun7i.h b/drivers/media/dvb/soc/dvb_drv_sun7i.h
new file mode 100644
index 0000000..d756767
--- /dev/null
+++ b/drivers/media/dvb/soc/dvb_drv_sun7i.h
@@ -0,0 +1,106 @@
+#ifndef DRIVER_INTERFACE_H
+#define DRIVER_INTERFACE_H
+
+#include<linux/ioctl.h>
+
+
+//define iocltl command
+#define TSCDEV_IOC_MAGIC 't'
+
+#define TSCDEV_ENABLE_INT _IO(TSCDEV_IOC_MAGIC, 0)
+#define TSCDEV_DISABLE_INT _IO(TSCDEV_IOC_MAGIC, 1)
+#define TSCDEV_GET_PHYSICS _IO(TSCDEV_IOC_MAGIC, 2)
+#define TSCDEV_RELEASE_SEM _IO(TSCDEV_IOC_MAGIC, 3)
+#define TSCDEV_WAIT_INT _IOR(TSCDEV_IOC_MAGIC, 4, unsigned long)
+#define TSCDEV_ENABLE_CLK _IOW(TSCDEV_IOC_MAGIC, 5, unsigned long)
+#define TSCDEV_DISABLE_CLK _IOW(TSCDEV_IOC_MAGIC, 6, unsigned long)
+#define TSCDEV_PUT_CLK _IOW(TSCDEV_IOC_MAGIC, 7, unsigned long)
+#define TSCDEV_SET_CLK_FREQ _IOW(TSCDEV_IOC_MAGIC, 8, unsigned long)
+#define TSCDEV_GET_CLK _IOWR(TSCDEV_IOC_MAGIC, 9, unsigned long)
+#define TSCDEV_GET_CLK_FREQ _IOWR(TSCDEV_IOC_MAGIC, 10, unsigned long)
+#define TSCDEV_SET_SRC_CLK_FREQ _IOWR(TSCDEV_IOC_MAGIC, 11, unsigned long)
+#define TSCDEV_FOR_TEST _IO(TSCDEV_IOC_MAGIC, 12)
+
+
+#define TSCDEV_IOC_MAXNR (12)
+
+
+struct intrstatus {
+ unsigned int port0chan;
+ unsigned int port0pcr;
+ unsigned int port1chan;
+ unsigned int port1pcr;
+};
+
+/*
+ * define struct for clock parameters
+ */
+#define CLK_NAME_LEN (32)
+struct clk_para {
+ char clk_name[CLK_NAME_LEN];
+ unsigned int handle;
+ int clk_rate;
+};
+
+/*
+ * define values of channel information
+ */
+#define TSF_INTR_THRESHOLD (1) // defines when to interrupt
+//0:1/2 buffer size 1:1/4 buffer size
+//2:1/8 buffer size 3:1/16 buffer size
+#define VIDEO_NOTIFY_PKT_NUM (1024)
+#define AUDIO_NOTIFY_PKT_NUM (64)
+#define SUBTITLE_NOTIFY_PKT_NUM (64)
+#define SECTION_NOTIFY_PKT_NUM (64)
+#define TS_DATA_NOTIFY_PKT_NUM (64)
+
+/*
+ * define channel max numbers and base offset
+ */
+#define VIDEO_CHAN_BASE (0)
+#define MAX_VIDEO_CHAN (1)
+
+#define AUDIO_CHAN_BASE (VIDEO_CHAN_BASE + MAX_VIDEO_CHAN)
+#define MAX_AUDIO_CHAN (1)
+
+#define SUBTITLE_CHAN_BASE (AUDIO_CHAN_BASE + MAX_AUDIO_CHAN)
+#define MAX_SUBTITLE_CHAN (1)
+
+#define SECTION_CHAN_BASE (SUBTITLE_CHAN_BASE + MAX_SUBTITLE_CHAN)
+#define MAX_SECTION_CHAN (12)
+
+#define TS_DATA_CHAN_BASE (SECTION_CHAN_BASE + MAX_SECTION_CHAN)
+#define MAX_TS_DATA_CHAN (15)
+
+/*
+ * define address of Registers
+ */
+#define REGS_pBASE (0x01C04000)
+
+// registers offset
+#define TSC_REGS_OFFSET (0x00 )
+#define TSG_REGS_OFFSET (0x40 )
+#define TSF0_REGS_OFFSET (0x80 )
+#define TSF1_REGS_OFFSET (0x100 )
+
+#define TSF0_PCR_STATUS_OFFSET (0x88 )
+#define TSF0_CHAN_STATUS_OFFSET (0x98 )
+#define TSF1_PCR_STATUS_OFFSET (0x108 )
+#define TSF1_CHAN_STATUS_OFFSET (0x118 )
+
+//start address
+#define TSC_REGS_pBASE (REGS_pBASE + 0x00 )
+#define TSG_REGS_pBASE (REGS_pBASE + 0x40 )
+#define TSF0_REGS_pBASE (REGS_pBASE + 0x80 )
+#define TSF1_REGS_pBASE (REGS_pBASE + 0x100)
+
+#define REGS_BASE REGS_pBASE
+#define TSC_REGS_BASE TSC_REGS_pBASE
+#define TSG_REGS_BASE TSG_REGS_pBASE
+#define TSF0_REGS_BASE TSF0_REGS_pBASE
+#define TSF1_REGS_BASE TSF1_REGS_pBASE
+
+//register size
+#define REGS_SIZE (0x1000)
+
+#endif
diff --git a/drivers/media/dvb/soc/tscdrv.c b/drivers/media/dvb/soc/tscdrv.c
new file mode 100644
index 0000000..9c40d70
--- /dev/null
+++ b/drivers/media/dvb/soc/tscdrv.c
@@ -0,0 +1,764 @@
+/*
+ * drivers/media/video/tsc/tscdrv.c
+ * (C) Copyright 2010-2015
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * csjamesdeng <csjam...@allwinnertech.com>
+ * (C) 2013 thomas....@gmail.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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/semaphore.h>
+#include <linux/fs.h>
+#include <linux/dma-mapping.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/cdev.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/preempt.h>
+#include <linux/rmap.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/module.h>
+#include <linux/ioctl.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/jiffies.h>
+#include <linux/gpio.h>
+
+#include <asm-generic/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/memory.h>
+#include <asm/unistd.h>
+#include <asm-generic/int-ll64.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/page.h>
+
+#include <plat/sys_config.h>
+#include <mach/gpio.h>
+#include <mach/clock.h>
+#include <mach/system.h>
+#include <mach/hardware.h>
+
+#include "tscdrv.h"
+
+
+static struct tsc_dev *tsc_devp = NULL;
+
+static DECLARE_WAIT_QUEUE_HEAD(wait_proc);
+
+/*
+ * unmap/release iomem
+ */
+static void tsiomem_unregister(struct tsc_dev *devp)
+{
+ /* Release io mem */
+ if (devp->regs) {
+ release_resource(devp->regs);
+ devp->regs = NULL;
+ }
+ iounmap(devp->regsaddr);
+ devp->regsaddr = NULL;
+}
+
+/*
+ * ioremap and request iomem
+ */
+static int register_tsiomem(struct tsc_dev *devp)
+{
+ char *addr;
+ int ret;
+ struct resource *res;
+
+ ret = check_mem_region(REGS_BASE, REGS_SIZE);
+ TSC_DBG("%s: check_mem_region return: %d\n", __func__, ret);
+ res = request_mem_region(REGS_BASE, REGS_SIZE, "ts regs");
+ if (res == NULL) {
+ TSC_ERR("%s: cannot reserve region for register\n", __func__);
+ goto err;
+ }
+ devp->regs = res;
+
+ addr = ioremap(REGS_BASE, REGS_SIZE);
+ if (!addr) {
+ TSC_ERR("%s: cannot map region for register\n", __func__);
+ goto err;
+ }
+
+ devp->regsaddr = addr;
+ TSC_DBG("%s: devp->regsaddr: 0x%08x\n", __func__, (unsigned int)devp->regsaddr);
+
+ return 0;
+
+err:
+ if (devp->regs) {
+ release_resource(devp->regs);
+ devp->regs = NULL;
+ }
+ return -1;
+}
+
+/*
+ * interrupt service routine
+ * To wake up wait queue
+ */
+static irqreturn_t tscdriverinterrupt(int irq, void *dev_id)
+{
+ tsc_devp->intstatus.port0pcr = ioread32((void *)(tsc_devp->regsaddr + 0x88));
+ tsc_devp->intstatus.port0chan = ioread32((void *)(tsc_devp->regsaddr + 0x98));
+ tsc_devp->intstatus.port1pcr = ioread32((void *)(tsc_devp->regsaddr + 0x108));
+ tsc_devp->intstatus.port1chan = ioread32((void *)(tsc_devp->regsaddr + 0x118));
+
+ iowrite32(tsc_devp->intstatus.port0pcr, (void *)(tsc_devp->regsaddr + 0x88));
+ iowrite32(tsc_devp->intstatus.port0chan, (void *)(tsc_devp->regsaddr + 0x98));
+ iowrite32(tsc_devp->intstatus.port1pcr, (void *)(tsc_devp->regsaddr + 0x108));
+ iowrite32(tsc_devp->intstatus.port1chan, (void *)(tsc_devp->regsaddr + 0x118));
+ tsc_devp->irq_flag = 1;
+
+ wake_up_interruptible(&wait_proc);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * poll operateion for wait for TS irq
+ */
+unsigned int tscdev_poll(struct file *filp, struct poll_table_struct *wait)
+{
+ int mask = 0;
+ struct tsc_dev *devp = filp->private_data;
+
+ poll_wait(filp, &devp->wq, wait);
+
+ if (devp->irq_flag == 1) {
+ mask |= POLLIN | POLLRDNORM;
+ }
+
+ return mask;
+}
+
+/*
+ * ioctl function
+ */
+long tscdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ long ret;
+ spinlock_t *lock;
+ struct tsc_dev *devp;
+ struct clk_para temp_clk;
+ struct clk *clk_hdle;
+ struct intrstatus statusdata;
+
+ ret = 0;
+ devp = filp->private_data;
+ lock = &devp->lock;
+
+ if (_IOC_TYPE(cmd) != TSCDEV_IOC_MAGIC)
+ return -EINVAL;
+ if (_IOC_NR(cmd) > TSCDEV_IOC_MAXNR)
+ return -EINVAL;
+
+ switch (cmd) {
+ case TSCDEV_WAIT_INT:
+ ret = wait_event_interruptible_timeout(wait_proc, devp->irq_flag, HZ * 1);
+ if (!ret && !devp->irq_flag) {
+ //case: wait timeout.
+ TSC_ERR("%s: wait timeout\n", __func__);
+ memset(&statusdata, 0, sizeof(statusdata));
+ } else {
+ //case: interrupt occured.
+ devp->irq_flag = 0;
+ statusdata.port0chan = devp->intstatus.port0chan;
+ statusdata.port0pcr = devp->intstatus.port0pcr;
+ statusdata.port1chan = devp->intstatus.port1chan;
+ statusdata.port1pcr = devp->intstatus.port1pcr;
+ }
+
+ //copy status data to user
+ if (copy_to_user((struct intrstatus *)arg, &(devp->intstatus),
+ sizeof(struct intrstatus))) {
+ return -EFAULT;
+ }
+
+ break;
+
+ case TSCDEV_GET_PHYSICS:
+ return virt_to_phys((void *)devp->pmem);
+
+ case TSCDEV_ENABLE_INT:
+ enable_irq(devp->irq);
+ break;
+
+ case TSCDEV_DISABLE_INT:
+ tsc_devp->irq_flag = 1;
+ wake_up_interruptible(&wait_proc);
+ disable_irq(devp->irq);
+ break;
+
+ case TSCDEV_RELEASE_SEM:
+ tsc_devp->irq_flag = 1;
+ wake_up_interruptible(&wait_proc);
+ break;
+
+ case TSCDEV_GET_CLK:
+ if (copy_from_user(&temp_clk, (struct clk_para __user *)arg,
+ sizeof(struct clk_para))) {
+ TSC_ERR("%s: get clk error\n", __func__);
+ return -EFAULT;
+ }
+ clk_hdle = clk_get(devp->dev, temp_clk.clk_name);
+
+ if (copy_to_user((char *) & ((struct clk_para *)arg)->handle,
+ &clk_hdle, 4)) {
+ TSC_ERR("%s: get clk error\n", __func__);
+ return -EFAULT;
+ }
+ break;
+
+ case TSCDEV_PUT_CLK:
+ if (copy_from_user(&temp_clk, (struct clk_para __user *)arg,
+ sizeof(struct clk_para))) {
+ TSC_ERR("%s: put clk error\n", __func__);
+ return -EFAULT;
+ }
+ clk_put((struct clk *)temp_clk.handle);
+
+ break;
+
+ case TSCDEV_ENABLE_CLK:
+ if (copy_from_user(&temp_clk, (struct clk_para __user *)arg,
+ sizeof(struct clk_para))) {
+ TSC_ERR("%s: enable clk error\n", __func__);
+ return -EFAULT;
+ }
+
+ clk_enable((struct clk *)temp_clk.handle);
+
+ break;
+
+ case TSCDEV_DISABLE_CLK:
+ if (copy_from_user(&temp_clk, (struct clk_para __user *)arg,
+ sizeof(struct clk_para))) {
+ TSC_ERR("%s: disable clk error\n", __func__);
+ return -EFAULT;
+ }
+
+ clk_disable((struct clk *)temp_clk.handle);
+
+ break;
+
+ case TSCDEV_GET_CLK_FREQ:
+ if (copy_from_user(&temp_clk, (struct clk_para __user *)arg,
+ sizeof(struct clk_para))) {
+ TSC_ERR("%s: get clk freq error\n", __func__);
+ return -EFAULT;
+ }
+ temp_clk.clk_rate = clk_get_rate((struct clk *)temp_clk.handle);
+
+ if (copy_to_user((char *) & ((struct clk_para *)arg)->clk_rate,
+ &temp_clk.clk_rate, 4)) {
+ TSC_ERR("%s: get clk freq error\n", __func__);
+ return -EFAULT;
+ }
+ break;
+
+ case TSCDEV_SET_SRC_CLK_FREQ:
+ break;
+
+ case TSCDEV_SET_CLK_FREQ:
+ if (copy_from_user(&temp_clk, (struct clk_para __user *)arg,
+ sizeof(struct clk_para))) {
+ TSC_ERR("%s: set clk error\n", __func__);
+ return -EFAULT;
+ }
+
+ clk_set_rate((struct clk *)temp_clk.handle, temp_clk.clk_rate);
+
+ break;
+
+ default:
+ TSC_ERR("%s: invalid cmd\n", __func__);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int tscdev_open(struct inode *inode, struct file *filp)
+{
+ int ret;
+ struct tsc_dev *devp;
+ struct clk_para tmp_clk;
+
+ devp = container_of(inode->i_cdev, struct tsc_dev, cdev);
+ filp->private_data = devp;
+
+ if (down_interruptible(&devp->sem)) {
+ return -ERESTARTSYS;
+ }
+
+ //open ahb clock
+ strcpy(tmp_clk.clk_name, "ahb_ts");
+ tsc_devp->ahb_clk = clk_get(tsc_devp->dev, tmp_clk.clk_name);
+ if (!tsc_devp->ahb_clk || IS_ERR(tsc_devp->ahb_clk)) {
+ TSC_ERR("%s: get ahb_ts clk failed\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ if (clk_enable(tsc_devp->ahb_clk) < 0) {
+ TSC_ERR("%s: enable ahb_ts clk error\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ TSC_INF("%s: ahb_ts clk rate: 0x%lx\n", __func__, clk_get_rate(tsc_devp->ahb_clk));
+
+ //open sdram clock
+ strcpy(tmp_clk.clk_name, "sdram_ts");
+ tsc_devp->sdram_clk = clk_get(tsc_devp->dev, tmp_clk.clk_name);
+ if (!tsc_devp->sdram_clk || IS_ERR(tsc_devp->sdram_clk)) {
+ TSC_ERR("%s: get sdram ts clk failed\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ if (clk_enable(tsc_devp->sdram_clk) < 0) {
+ TSC_ERR("%s: enable sdram ts clk error\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ //open ts clock
+ strcpy(tmp_clk.clk_name, "ts");
+ tsc_devp->tsc_clk = clk_get(tsc_devp->dev, tmp_clk.clk_name);
+ if (!tsc_devp->tsc_clk || IS_ERR(tsc_devp->tsc_clk)) {
+ TSC_ERR("%s: get tsc clk failed\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ if (clk_enable(tsc_devp->tsc_clk) < 0) {
+ TSC_ERR("%s: enable tsc clk error\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ strcpy(tmp_clk.clk_name, "sdram_pll_p");
+ tsc_devp->pll5_clk = clk_get(tsc_devp->dev, tmp_clk.clk_name);
+ if (!tsc_devp->pll5_clk || IS_ERR(tsc_devp->pll5_clk)) {
+ TSC_ERR("%s: get pll5 clk failed\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ clk_set_parent(tsc_devp->tsc_clk, tsc_devp->pll5_clk);
+
+ //set ts clock rate
+ tmp_clk.clk_rate = clk_get_rate(tsc_devp->pll5_clk);
+ TSC_INF("%s: parent clock rate %d\n", __func__, tmp_clk.clk_rate);
+ tmp_clk.clk_rate /= 2;
+ TSC_INF("%s: clock rate %d\n", __func__, tmp_clk.clk_rate);
+ if (clk_set_rate(tsc_devp->tsc_clk, tmp_clk.clk_rate) < 0) {
+ TSC_INF("%s: set clk rate error\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ tmp_clk.clk_rate = clk_get_rate(tsc_devp->tsc_clk);
+ TSC_INF("%s: clock rate %d", __func__, tmp_clk.clk_rate);
+
+ /* init other resource here */
+ devp->irq_flag = 0;
+
+ up(&devp->sem);
+
+ nonseekable_open(inode, filp);
+
+ return 0;
+
+err:
+ if (devp->tsc_clk) {
+ clk_disable(tsc_devp->tsc_clk);
+ devp->tsc_clk = NULL;
+ }
+ if (devp->ahb_clk) {
+ clk_disable(tsc_devp->ahb_clk);
+ devp->ahb_clk = NULL;
+ }
+ if (devp->sdram_clk) {
+ clk_disable(tsc_devp->sdram_clk);
+ devp->sdram_clk = NULL;
+ }
+
+ return ret;
+}
+
+static int tscdev_release(struct inode *inode, struct file *filp)
+{
+ struct tsc_dev *devp;
+
+ devp = filp->private_data;
+
+ if (down_interruptible(&devp->sem)) {
+ return -ERESTARTSYS;
+ }
+
+ if (devp->tsc_clk) {
+ clk_disable(tsc_devp->tsc_clk);
+ devp->tsc_clk = NULL;
+ }
+ if (devp->ahb_clk) {
+ clk_disable(tsc_devp->ahb_clk);
+ devp->ahb_clk = NULL;
+ }
+ if (devp->sdram_clk) {
+ clk_disable(tsc_devp->sdram_clk);
+ devp->sdram_clk = NULL;
+ }
+
+ /* release other resource here */
+ devp->irq_flag = 1;
+
+ up(&devp->sem);
+
+ return 0;
+}
+
+void tscdev_vma_open(struct vm_area_struct *vma)
+{
+ TSC_DBG("%s\n", __func__);
+}
+
+void tscdev_vma_close(struct vm_area_struct *vma)
+{
+ TSC_DBG("%s\n", __func__);
+}
+
+static struct vm_operations_struct tscdev_remap_vm_ops = {
+ .open = tscdev_vma_open,
+ .close = tscdev_vma_close,
+};
+
+static int tscdev_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ unsigned int mypfn;
+ unsigned int psize;
+ unsigned int offset;
+ unsigned int physics;
+ unsigned int vmsize;
+ unsigned int regsaddr ;
+ struct tsc_dev *devp = filp->private_data;
+
+ regsaddr = (unsigned int)devp->regsaddr ;
+ offset = vma->vm_pgoff << PAGE_SHIFT;
+ vmsize = vma->vm_end - vma->vm_start;
+ psize = devp->gsize - offset;
+ if (vmsize <= PAGE_SIZE) { // if mmap registers, vmsize must be less than PAGE_SIZE
+ physics = __pa(regsaddr);
+ mypfn = REGS_BASE >> 12;
+
+ vma->vm_flags |= VM_RESERVED | VM_IO;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ if (remap_pfn_range(vma, vma->vm_start, mypfn, vmsize, vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ } else {
+ physics = __pa(devp->pmem);
+ mypfn = physics >> PAGE_SHIFT;
+ if (vmsize > psize)
+ return -ENXIO;
+
+ vma->vm_flags |= VM_RESERVED ;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ if (remap_pfn_range(vma, vma->vm_start, mypfn, vmsize, vma->vm_page_prot)) {
+ return -EAGAIN;
+ }
+ }
+
+ vma->vm_ops = &tscdev_remap_vm_ops;
+ tscdev_vma_open(vma);
+
+ return 0;
+}
+
+static unsigned p_gpio_handler = 0;
+
+static unsigned int request_tsc_pio(void)
+{
+ int cnt;
+ user_gpio_set_t gpio_list;
+
+ cnt = script_parser_mainkey_get_gpio_count("tsc_para");
+ if (!script_parser_mainkey_get_gpio_cfg("tsc_para", &gpio_list, cnt)) {
+ TSC_ERR("%s: get tsc pio para failed\n", __func__);
+ return -1;
+ }
+
+ if (!(p_gpio_handler = sunxi_gpio_request_array(&gpio_list, cnt))) {
+ TSC_INF("%s: request tsc pio failed, maybe error\n", __func__);
+ goto err;
+ }
+ return 0;
+
+err:
+ gpio_release(p_gpio_handler, 1);
+ return -1;
+}
+
+static void release_tsc_pio(void)
+{
+ gpio_release(p_gpio_handler, 1);
+}
+
+static struct file_operations tscdev_fops = {
+ .owner = THIS_MODULE,
+ .mmap = tscdev_mmap,
+ .poll = tscdev_poll,
+ .open = tscdev_open,
+ .release = tscdev_release,
+ .llseek = no_llseek,
+ .unlocked_ioctl = tscdev_ioctl,
+};
+
+static int size_multiply_arr[4] = {2, 4, 8, 16};
+static int tsc_used = 0;
+
+static int __init tscdev_init(void)
+{
+ int ret;
+ int devno;
+ unsigned int videobufsize;
+ unsigned int audiobufsize;
+ unsigned int subtitlebufsize;
+ unsigned int sectionbufsize;
+ unsigned int tsdatabufsize;
+ unsigned int pcrbufsize;
+ unsigned int chan32bufsize;
+ unsigned int sizemultiply;
+ char *viraddr;
+ char *pbuf;
+ int gsize;
+ dev_t dev = 0;
+ int *val = NULL;
+
+ if(!(script_parser_fetch_ex("tsc_para", "tsc_used", val,
+ (script_parser_value_type_t*)SCRIPT_PARSER_VALUE_TYPE_SINGLE_WORD, 1))) {
+ TSC_ERR("%s: get tsc_used failed\n", __func__);
+ return 0;
+ }
+ if (*val != 1) {
+ TSC_INF("%s: tsc driver is disabled\n", __func__);
+ return 0;
+ }
+ tsc_used = *val;
+
+ tsc_devp = kmalloc(sizeof(struct tsc_dev), GFP_KERNEL);
+ if (tsc_devp == NULL) {
+ TSC_ERR("%s: malloc memory for tsc device error\n", __func__);
+ return -ENOMEM;
+ }
+ memset(tsc_devp, 0, sizeof(struct tsc_dev));
+
+ tsc_devp->ts_dev_major = TSCDEV_MAJOR;
+ tsc_devp->ts_dev_minor = TSCDEV_MINOR;
+
+ /* register char device */
+ dev = MKDEV(tsc_devp->ts_dev_major, tsc_devp->ts_dev_minor);
+ if (tsc_devp->ts_dev_major) {
+ ret = register_chrdev_region(dev, 1, "tsc_dev");
+ } else {
+ ret = alloc_chrdev_region(&dev, tsc_devp->ts_dev_minor, 1, "tsc_dev");
+ tsc_devp->ts_dev_major = MAJOR(dev);
+ tsc_devp->ts_dev_minor = MINOR(dev);
+ }
+ if (ret < 0) {
+ TSC_ERR("%s: can't get major %d", __func__, tsc_devp->ts_dev_major);
+ goto err1;
+ }
+
+ /* calculate total buffer size of filters */
+ sizemultiply = size_multiply_arr[TSF_INTR_THRESHOLD];
+ videobufsize = (VIDEO_NOTIFY_PKT_NUM * 188 * sizemultiply + 0x3ff)& ~0x3ff;
+ audiobufsize = (AUDIO_NOTIFY_PKT_NUM * 188 * sizemultiply + 0x3ff)& ~0x3ff;
+ subtitlebufsize = (SUBTITLE_NOTIFY_PKT_NUM * 188 * sizemultiply + 0x3ff)& ~0x3ff;
+ sectionbufsize = (SECTION_NOTIFY_PKT_NUM * 188 * sizemultiply + 0x3ff)& ~0x3ff;
+ tsdatabufsize = (TS_DATA_NOTIFY_PKT_NUM * 188 * sizemultiply + 0x3ff)& ~0x3ff;
+ pcrbufsize = (1 * 188 * sizemultiply + 0x3ff) & ~0x3ff;;
+ chan32bufsize = (1 * 188 * sizemultiply + 0x3ff) & ~0x3ff;;
+
+ gsize = videobufsize * MAX_VIDEO_CHAN +
+ audiobufsize * MAX_AUDIO_CHAN +
+ subtitlebufsize * MAX_SUBTITLE_CHAN +
+ sectionbufsize * MAX_SECTION_CHAN +
+ tsdatabufsize * MAX_TS_DATA_CHAN +
+ pcrbufsize +
+ chan32bufsize;
+
+ /* alloc contiguous buffer */
+ gsize = (gsize + 0xfff) & ~0xfff;
+ TSC_INF("%s: kmalloc memory, size: 0x%x\n", __func__, gsize);
+ pbuf = (char *)kmalloc(gsize, GFP_DMA | GFP_KERNEL);
+ if (!pbuf) {
+ TSC_ERR("%s: allocate memory failed\n", __func__);
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ /* set pages reversed */
+ for (viraddr = pbuf; viraddr < pbuf + gsize; viraddr += PAGE_SIZE) {
+ SetPageReserved(virt_to_page(viraddr));
+ }
+
+ tsc_devp->pmem = pbuf;
+ tsc_devp->gsize = gsize;
+
+ sema_init(&tsc_devp->sem, 1);
+ init_waitqueue_head(&tsc_devp->wq);
+
+ /* request TS pio */
+ if (request_tsc_pio()) {
+ TSC_ERR("%s: request tsc pio failed\n", __func__);
+ ret = -EINVAL;
+ goto err2;
+ }
+
+ /* request TS irq */
+ ret = request_irq(TS_IRQ_NO, tscdriverinterrupt, 0, "tsc_dev", NULL);
+ if (ret < 0) {
+ TSC_ERR("%s: request irq error\n", __func__);
+ ret = -EINVAL;
+ goto err3;
+ }
+ tsc_devp->irq = TS_IRQ_NO;
+
+ /* create char device */
+ devno = MKDEV(tsc_devp->ts_dev_major, tsc_devp->ts_dev_minor);
+ cdev_init(&tsc_devp->cdev, &tscdev_fops);
+ tsc_devp->cdev.owner = THIS_MODULE;
+ tsc_devp->cdev.ops = &tscdev_fops;
+ ret = cdev_add(&tsc_devp->cdev, devno, 1);
+ if (ret) {
+ TSC_ERR("%s: add tsc char device error\n", __func__);
+ ret = -EINVAL;
+ goto err4;
+ }
+
+ tsc_devp->class = class_create(THIS_MODULE, "tsc_dev");
+ if (IS_ERR(tsc_devp->class)) {
+ TSC_ERR("%s: create tsc_dev class failed\n", __func__);
+ ret = -EINVAL;
+ goto err5;
+ }
+
+ tsc_devp->dev = device_create(tsc_devp->class, NULL, devno, NULL, "tsc_dev");
+ if (IS_ERR(tsc_devp->dev)) {
+ TSC_ERR("%s: create tsc_dev device failed\n", __func__);
+ ret = -EINVAL;
+ goto err6;
+ }
+
+ if (register_tsiomem(tsc_devp)) {
+ TSC_ERR("%s: register ts io memory error\n", __func__);
+ ret = -EINVAL;
+ goto err7;
+ }
+
+ return 0;
+
+err7:
+ device_destroy(tsc_devp->class, dev);
+err6:
+ class_destroy(tsc_devp->class);
+err5:
+ cdev_del(&tsc_devp->cdev);
+err4:
+ free_irq(TS_IRQ_NO, NULL);
+err3:
+ release_tsc_pio();
+err2:
+ if (tsc_devp->pmem) {
+ /* release reserved pages */
+ for (viraddr = pbuf; viraddr < pbuf + gsize; viraddr += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(viraddr));
+ }
+ kfree(pbuf);
+ pbuf = NULL;
+ }
+err1:
+ unregister_chrdev_region(dev, 1);
+ if (tsc_devp) {
+ kfree(tsc_devp);
+ }
+
+ return ret;
+}
+module_init(tscdev_init);
+
+static void __exit tscdev_exit(void)
+{
+ dev_t dev;
+ char *viraddr;
+ char *pbuf;
+ int gsize;
+
+ if (tsc_used != 1) {
+ TSC_INF("%s: tsc driver is disabled\n", __func__);
+ return;
+ }
+
+ if (tsc_devp == NULL) {
+ TSC_ERR("%s: invalid tsc_devp\n", __func__);
+ return;
+ }
+
+ /* unregister iomem and iounmap */
+ tsiomem_unregister(tsc_devp);
+
+ dev = MKDEV(tsc_devp->ts_dev_major, tsc_devp->ts_dev_minor);
+ device_destroy(tsc_devp->class, dev);
+ class_destroy(tsc_devp->class);
+ cdev_del(&tsc_devp->cdev);
+
+ /* release ts irq */
+ free_irq(TS_IRQ_NO, NULL);
+
+ /* release ts pin */
+ release_tsc_pio();
+
+ pbuf = tsc_devp->pmem;
+ gsize = tsc_devp->gsize;
+ if (tsc_devp->pmem) {
+ /* release reserved pages */
+ for (viraddr = pbuf; viraddr < pbuf + gsize; viraddr += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(viraddr));
+ }
+ kfree(pbuf);
+ pbuf = NULL;
+ }
+
+ unregister_chrdev_region(dev, 1);
+
+ kfree(tsc_devp);
+}
+module_exit(tscdev_exit);
+
+MODULE_AUTHOR("Soft-Allwinner");
+MODULE_DESCRIPTION("Allwinner Transport Stream Controller (TSC) driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/media/dvb/soc/tscdrv.h b/drivers/media/dvb/soc/tscdrv.h
new file mode 100644
index 0000000..b34a15c
--- /dev/null
+++ b/drivers/media/dvb/soc/tscdrv.h
@@ -0,0 +1,74 @@
+/*
+ * drivers/media/video/tsc/tscdrv.c
+ * (C) Copyright 2010-2015
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * csjamesdeng <csjam...@allwinnertech.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.
+ *
+ */
+
+#ifndef __TSC_DRV_H__
+#define __TSC_DRV_H__
+
+#include "dvb_drv_sun7i.h"
+
+#define DRV_VERSION "0.0.3alpha" //version
+#define TS_IRQ_NO (35) //interrupt number,
+
+#ifndef TSCDEV_MAJOR
+#define TSCDEV_MAJOR (225)
+#endif
+
+#ifndef TSCDEV_MINOR
+#define TSCDEV_MINOR (0)
+#endif
+
+struct tsc_dev {
+ struct cdev cdev; /* char device struct */
+ struct device *dev; /* ptr to class device struct */
+ struct class *class; /* class for auto create device node */
+ struct semaphore sem; /* mutual exclusion semaphore */
+ spinlock_t lock; /* spinlock to protect ioclt access */
+ wait_queue_head_t wq; /* wait queue for poll ops */
+
+ struct resource *regs; /* registers resource */
+ char *regsaddr ; /* registers address */
+
+ unsigned int irq; /* tsc driver irq number */
+ unsigned int irq_flag; /* flag of tsc driver irq generated */
+
+ int ts_dev_major;
+ int ts_dev_minor;
+
+ struct clk *pll5_clk;
+ struct clk *sdram_clk; /* sdram clock */
+ struct clk *tsc_clk; /* ts clock */
+ struct clk *ahb_clk; /* ahb clock */
+
+ char *pmem; /* memory address */
+ unsigned int gsize; /* memory size */
+
+ struct intrstatus intstatus; /* save interrupt status */
+};
+
+#define TSC_DEBUG_LEVEL 3
+
+#if (TSC_DEBUG_LEVEL == 1)
+ #define TSC_DBG(format,args...) do {} while (0)
+ #define TSC_INF(format,args...) do {} while (0)
+ #define TSC_ERR(format,args...) printk(KERN_ERR "[tsc-err] "format,##args)
+#elif (TSC_DEBUG_LEVEL == 2)
+ #define TSC_DBG(format,args...) do {} while (0)
+ #define TSC_INF(format,args...) printk(KERN_INFO"[tsc-inf] "format,##args)
+ #define TSC_ERR(format,args...) printk(KERN_ERR "[tsc-err] "format,##args)
+#elif (TSC_DEBUG_LEVEL == 3)
+ #define TSC_DBG(format,args...) printk(KERN_INFO"[tsc-dbg] "format,##args)
+ #define TSC_INF(format,args...) printk(KERN_INFO"[tsc-inf] "format,##args)
+ #define TSC_ERR(format,args...) printk(KERN_ERR "[tsc-err] "format,##args)
+#endif
+
+#endif

--





thomas schorpp

unread,
Aug 11, 2013, 4:02:39 PM8/11/13
to linux...@googlegroups.com
OK, IMHO corrected type mismatches changed to gpio_request_ex() because all of the fun
in there and this version should at least load the driver
but gpio_init fails due to prog error or missing gpio setup in script.bin.
Still problems with module linking and don't know yet if gpio_init() is needed.

[ 2086.006965] [tsc-inf] tscdev_init: kmalloc memory, size: 0x212000
[ 2086.020209] gpio count < =0 ,gpio_count is: 0
[ 2086.030438] [tsc-inf] request_tsc_pio: request tsc pio failed, maybe error
[ 2086.042865] [tsc-err] tscdev_init: request tsc pio failed

If no docs available for tsc_para I try modified setup from the csi_para section.

Patch for olimex A20 fex file attached, too.

Signed-off-by: Thomas Schorpp <thomas....@gmail.com>

---

diff --git a/sys_config/a20/a20-olinuxino_micro.fex b/sys_config/a20/a20-olinuxino_micro.fex
index dd2835a..0bba2dd 100644
--- a/sys_config/a20/a20-olinuxino_micro.fex
+++ b/sys_config/a20/a20-olinuxino_micro.fex
@@ -461,6 +461,9 @@ dac3_src = 0
[hdmi_para]
hdmi_used = 1

+[tsc_para]
+tsc_used = 1
+
[camera_list_para]
camera_list_para_used = 0
ov7670 = 0
index 0000000..ad259cc
--- /dev/null
+++ b/drivers/media/dvb/soc/tscdrv.c
@@ -0,0 +1,754 @@
+ if (!(p_gpio_handler = gpio_request_ex("tsc_para", NULL))) {
+ int val = 0;
+
+ if((script_parser_fetch("tsc_para", "tsc_used", &val, sizeof(int))) < 0 ) {
+ TSC_ERR("%s: get tsc_used failed\n", __func__);
+ return 0;
+ }
+ if (val != 1) {
+ TSC_INF("%s: tsc driver is disabled\n", __func__);
+ return 0;
+ }
+ tsc_used = val;
index 0000000..5fe3f48
--- /dev/null
+++ b/drivers/media/dvb/soc/tscdrv.h
@@ -0,0 +1,74 @@
+/*
+ * drivers/media/video/tsc/tscdrv.c
+ * (C) Copyright 2010-2015
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * csjamesdeng <csjam...@allwinnertech.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.
+ *
+ */
+
+#ifndef __TSC_DRV_H__
+#define __TSC_DRV_H__
+
+#include "dvb_drv_sun7i.h"
+
+#define DRV_VERSION "0.0.4alpha" //version

Hans de Goede

unread,
Aug 12, 2013, 9:55:47 AM8/12/13
to linux...@googlegroups.com, thomas schorpp
Hi,

On 08/11/2013 10:02 PM, thomas schorpp wrote:
> OK, IMHO corrected type mismatches changed to gpio_request_ex() because all of the fun
> in there and this version should at least load the driver
> but gpio_init fails due to prog error or missing gpio setup in script.bin.
> Still problems with module linking and don't know yet if gpio_init() is needed.

Sounds to me like this is not ready for merging yet then. Please send a new
version when you've resolved these issues and then I'll add it to my sunxi-3.4 tree.

Regards,

Hans

thomas schorpp

unread,
Aug 14, 2013, 1:44:15 PM8/14/13
to linux...@googlegroups.com, linux...@vger.kernel.org
OK, with the patched fex file and devices.c from
[linux-sunxi] [PATCH v2 1/1] [sunxi-boards/a20] Add support for Allwinner (DVB/ATSC) Transport Stream Controller(s) (TSC)
[PATCH v2 1/1] [stage/sunxi-3.4] sw_nand: sunxi devices core using wrong MMIO region range, overlaps TSC/TSI register base address 0x01c04000
and the driver patches from this topic here

the driver basically loads and inits:

[ 161.016837] [tsc-inf] tscdev_init: kmalloc memory, size: 0x212000
[ 161.042378] [tsc-dbg] register_tsiomem: check_mem_region return: 0
[ 161.055409] [tsc-dbg] register_tsiomem: devp->regsaddr: 0xf0104000

root@vdr2:~# cat /proc/iomem |grep -C 1 -i ts
01c03000-01c03fff : sw_nand
01c04000-01c04fff : ts regs
01c0a000-01c0afff : disp

root@vdr2:~# ls -l /dev/ts*
crw------- 1 root root 225, 0 Aug 14 19:10 /dev/tsc_dev

And ioctl() triggers the controller setup successfully.

root@vdr2:~# dd if=/dev/tsc_dev of=/dev/null bs=1K count=100 &

[ 1064.861178] [tsc-inf] tscdev_open: ahb_ts clk rate: 0x1
[ 1064.871506] [tsc-inf] tscdev_open: parent clock rate 384000000
[ 1064.881674] [tsc-inf] tscdev_open: clock rate 192000000
[ 1064.891079] [tsc-inf] tscdev_open: clock rate 192000000

Ready to build the Philips CU1216-MKIII TDA10023 DVB-C- Receiver "recycling" SMT extension board next days.
Others are invited to build boards with their receiver modules and extend driver Kconfig for more receivers, too.

Next i2c and frontend driver integration, if someone can do that faster, pls don't wait for me and pls CC linux-media list.

dvb_core integration after the hardware and driver PIO tests success.

Thanks for all the great community support :-)

y
tom

Oliver Schinagl

unread,
Aug 21, 2013, 2:44:02 AM8/21/13
to linux...@googlegroups.com
On 09-08-13 18:23, thomas schorpp wrote:
> Please report boards and AW SoC types with TS0 AND TS1 inputs available
> and in which GPIO multiplex mode.
A10 and A20 should have both TS0 and TS1 pins mapped on the Olimexino
Micro boards (According to the datasheet anyway).

oliver

John S

unread,
Aug 21, 2013, 3:38:15 AM8/21/13
to linux...@googlegroups.com
In case anyone doesn't know, Olimex put their schematics (and more) on their site as they are an Open Hardware company.

John


From: Oliver Schinagl <olive...@schinagl.nl>
To: linux...@googlegroups.com
Sent: Wednesday, 21 August 2013, 7:44
Subject: Re: [linux-sunxi] [PATCH v3 1/1] [stage/sunxi-3.4] Add support for Allwinner (DVB/ATSC) Transport Stream Controller(s) (TSC)

thomas schorpp

unread,
Sep 12, 2013, 1:43:04 PM9/12/13
to linux...@googlegroups.com, John S
Am 21.08.2013 09:38, schrieb John S:
> In case anyone doesn't know, Olimex put their schematics (and more) on their site as they are an Open Hardware company.
>
> John
>

Git-Web: https://github.com/OLIMEX/OLINUXINO/tree/master/HARDWARE

Pull from git or https://github.com/OLIMEX/OLINUXINO.git

Thank You Olimex staff.

y
tom

thomas schorpp

unread,
Sep 16, 2013, 4:33:41 PM9/16/13
to linux...@googlegroups.com, John S
Am 21.08.2013 09:38, schrieb John S:
> In case anyone doesn't know, Olimex put their schematics (and more) on their site as they are an Open Hardware company.
>
> John
>

You should state the Eagle versions used in a README, Eagle Light 5.12.0 from debian stable cannot open Your latest
A10-A20 micro *.sch and *brd files,

had to manually download and install version 6.5.0 on the vdr machine running debian testing, depends on libssl 1.0.0 a.o.

y
tom





John S

unread,
Sep 16, 2013, 4:58:54 PM9/16/13
to linux...@googlegroups.com
Er, don't know why you sent this to me?

I don't work for Olimex.

I've never used Eagle.

John


From: thomas schorpp <thomas....@gmail.com>
To: linux...@googlegroups.com
Cc: John S <johns9...@yahoo.co.uk>
Sent: Monday, 16 September 2013, 21:33

Subject: Re: [linux-sunxi] [PATCH v3 1/1] [stage/sunxi-3.4] Add support for Allwinner (DVB/ATSC) Transport Stream Controller(s) (TSC)
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsub...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


anuroo...@gmail.com

unread,
Aug 12, 2014, 2:25:21 AM8/12/14
to linux...@googlegroups.com, linux...@vger.kernel.org, thomas....@gmail.com

Hi, I need some help. I am trying to take TS stream input through TS0 Allwinner A20 board by SMDT.
I have the Fex file info as below.
[tsc_para]
tsc_used = 1
tsc_cla = port:PE00<2><default><default><default>
tsc_err = port:PE01<2><default><default><default>
tsc_sync = port:PE02<2><default><default><default>
tsc_dvld = port:PE03<2><default><default><default>
tsc_d0 = port:PE04<2><default><default><default>
tsc_d1 = port:PE05<2><default><default><default>
tsc_d2 = port:PE06<2><default><default><default>
tsc_d3 = port:PE07<2><default><default><default>
tsc_d4 = port:PE08<2><default><default><default>
tsc_d5 = port:PE09<2><default><default><default>
tsc_d6 = port:PE10<2><default><default><default>
tsc_d7 = port:PE11<2><default><default><default>

Now, with this I get some error when I load the tscdrv.ko.
below are the errors
<6>[ 775.488646] [tsc-inf] tscdev_init: kmalloc memory, size: 0x212000
<6>[ 775.509833] [tsc-inf] request_tsc_pio: request tsc pio119 failed, maybe error
<6>[ 775.509889] [tsc-inf] request_tsc_pio: request tsc pio120 failed, maybe error
<6>[ 775.509934] [tsc-inf] request_tsc_pio: request tsc pio121 failed, maybe error
<6>[ 775.509979] [tsc-inf] request_tsc_pio: request tsc pio122 failed, maybe error
<6>[ 775.510023] [tsc-inf] request_tsc_pio: request tsc pio123 failed, maybe error
<6>[ 775.510067] [tsc-inf] request_tsc_pio: request tsc pio124 failed, maybe error
<6>[ 775.510112] [tsc-inf] request_tsc_pio: request tsc pio125 failed, maybe error
<6>[ 775.510156] [tsc-inf] request_tsc_pio: request tsc pio126 failed, maybe error
<6>[ 775.510200] [tsc-inf] request_tsc_pio: request tsc pio127 failed, maybe error
<6>[ 775.510245] [tsc-inf] request_tsc_pio: request tsc pio128 failed, maybe error
<6>[ 775.510289] [tsc-inf] request_tsc_pio: request tsc pio129 failed, maybe error
<6>[ 775.510333] [tsc-inf] request_tsc_pio: request tsc pio130 failed, maybe error
<6>[ 775.514859] [tsc-dbg] register_tsiomem: check_mem_region return: 0
<6>[ 775.514991] [tsc-dbg] register_tsiomem: devp->regsaddr: 0xf0012000

am I missing something? Do I need to modify the fex file?

please forgive me if my questions are wrong. I am fairly new to android & Allwinner platform.

thanks a lot
Anuroop

thomas schorpp

unread,
Aug 12, 2014, 3:56:01 AM8/12/14
to anuroo...@gmail.com, linux...@googlegroups.com, linux...@vger.kernel.org
Am 12.08.2014 um 08:25 schrieb anuroo...@gmail.com:
> On Wednesday, August 14, 2013 11:14:15 PM UTC+5:30, Thomas Schorpp wrote:
>> OK, with the patched fex file and devices.c from
>>
>> [linux-sunxi] [PATCH v2 1/1] [sunxi-boards/a20] Add support for Allwinner (DVB/ATSC) Transport Stream Controller(s) (TSC)
>>
>> [PATCH v2 1/1] [stage/sunxi-3.4] sw_nand: sunxi devices core using wrong MMIO region range, overlaps TSC/TSI register base address 0x01c04000
>>
>> and the driver patches from this topic here
>>
>>
>
>>
>> the driver basically loads and inits:

>
> please forgive me if my questions are wrong. I am fairly new to android & Allwinner platform.

1. The tscdrv.c code (my linux-sunxi port, too) is (c) AW proprietary, You need to contact AW support (+ for a complete TSC Manual).

2. I've suspended my TSC project until a complete A20 TSC manual is available or I get the time for register probe rev. engineering.

3. https://groups.google.com/forum/#!topic/android-porting/EMAG4RUlOjI

"Now we are planning to integrate a TV chip with this (DVB-T) . Allwinner has TS control block and a sample driver along with it."

Who is "we"?

I don't support Android OS platform, nor do "we" support closed source product developers from hidden proprietary products manufacturers
usually not releasing derivated works of GPL'd code back to "us" or the android-porting project with their products,
especially not for free. Please refer to the known consultant companies if Your company needs "help".

Please, tell Your Boss there's a big difference between "help" and valuable expensive engineering project consulting, thank You.
Code maybe free under GPL (only the without warranty version) but consulting for it is not, and violating the GPL is breaking the law, worldwide.

This is the second request directly adressed to me off-list from a commercial company to work for free for them,
I will drop any further to the JUNK Mail folder without notice.

>
> thanks a lot
> Anuroop
>

thanks A LOT :-//
y
tom

anuroo...@gmail.com

unread,
Aug 12, 2014, 4:51:05 AM8/12/14
to linux...@googlegroups.com, anuroo...@gmail.com, linux...@vger.kernel.org, thomas....@gmail.com

I am sorry Tom. I was trying to build the AW TSC for SMDT.
hope you forgive me for my mistakes.

-thanks
Anuroop

Mihail Tommonen

unread,
Aug 12, 2014, 8:21:27 AM8/12/14
to linux...@googlegroups.com, anuroo...@gmail.com, linux...@vger.kernel.org, thomas....@gmail.com

Hi,


2. I've suspended my TSC project until a complete A20 TSC manual is available or I get the time for register probe rev. engineering.

Have you seen this: http://dl.linux-sunxi.org/A10/A10%20Transport%20Stream%20Controller%20V1.00%2020120917.pdf
I expect a20 tsc to be really similiart to a10.

WBR

Miska

thomas schorpp

unread,
Aug 12, 2014, 9:24:38 AM8/12/14
to Mihail Tommonen, linux...@googlegroups.com, anuroo...@gmail.com, linux...@vger.kernel.org
Incomplete. Prove me wrong by getting a full TS without bypassing the TSC using the GPIO ports in other MUX mode directly, if possible (sig speed).

>
> WBR
>
> Miska
>

y
tom

anuroop kamu

unread,
Aug 12, 2014, 11:20:16 AM8/12/14
to Mihail Tommonen, linux...@googlegroups.com, linux...@vger.kernel.org
Hi Miska, Thanks for that Doc

I am still not able to visualize it fully. if this Tsc driver works well, which buffer/fifo will the data be available? 
Do I need to make a separate media player app to get this data? Or any default media player can play the video directly from /dev/tsc_dev (or /dev/video0) ?
I am trying to use the default AW TS driver for A20.

please correct me if my understanding is wrong.

thanks
Anuroop 

yang...@gmail.com

unread,
Feb 4, 2016, 1:48:44 AM2/4/16
to linux-sunxi, patap...@gmail.com, linux...@vger.kernel.org
在 2014年8月12日星期二 UTC+8下午11:20:16,anuroop kamu写道:
hi
you must have a tsdeviver like dibcom 3000 or anything,so you can done it.
Reply all
Reply to author
Forward
0 new messages