aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/isdbt
diff options
context:
space:
mode:
authorcodeworkx <daniel.hillenbrand@codeworkx.de>2012-06-02 13:09:29 +0200
committercodeworkx <daniel.hillenbrand@codeworkx.de>2012-06-02 13:09:29 +0200
commitc6da2cfeb05178a11c6d062a06f8078150ee492f (patch)
treef3b4021d252c52d6463a9b3c1bb7245e399b009c /drivers/media/isdbt
parentc6d7c4dbff353eac7919342ae6b3299a378160a6 (diff)
downloadkernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.zip
kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.gz
kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.bz2
samsung update 1
Diffstat (limited to 'drivers/media/isdbt')
-rw-r--r--drivers/media/isdbt/Kconfig5
-rw-r--r--drivers/media/isdbt/Makefile7
-rw-r--r--drivers/media/isdbt/fc8100/KLlist.c285
-rw-r--r--drivers/media/isdbt/fc8100/LKlist.h44
-rw-r--r--drivers/media/isdbt/fc8100/Makefile16
-rw-r--r--drivers/media/isdbt/fc8100/bbm.c237
-rw-r--r--drivers/media/isdbt/fc8100/bbm.h61
-rw-r--r--drivers/media/isdbt/fc8100/fc8100.c271
-rw-r--r--drivers/media/isdbt/fc8100/fc8100.h66
-rw-r--r--drivers/media/isdbt/fc8100/fc8100_bb.c204
-rw-r--r--drivers/media/isdbt/fc8100/fc8100_bb.h29
-rw-r--r--drivers/media/isdbt/fc8100/fc8100_i2c.c349
-rw-r--r--drivers/media/isdbt/fc8100/fc8100_i2c.h43
-rw-r--r--drivers/media/isdbt/fc8100/fc8100_isr.c27
-rw-r--r--drivers/media/isdbt/fc8100/fc8100_isr.h31
-rw-r--r--drivers/media/isdbt/fc8100/fc8100_regs.h337
-rw-r--r--drivers/media/isdbt/fc8100/fc8100_tun.c351
-rw-r--r--drivers/media/isdbt/fc8100/fc8100_tun.h29
-rw-r--r--drivers/media/isdbt/fc8100/fci_hal.c199
-rw-r--r--drivers/media/isdbt/fc8100/fci_hal.h41
-rw-r--r--drivers/media/isdbt/fc8100/fci_i2c.c42
-rw-r--r--drivers/media/isdbt/fc8100/fci_i2c.h31
-rw-r--r--drivers/media/isdbt/fc8100/fci_oal.c34
-rw-r--r--drivers/media/isdbt/fc8100/fci_oal.h27
-rw-r--r--drivers/media/isdbt/fc8100/fci_tun.c162
-rw-r--r--drivers/media/isdbt/fc8100/fci_tun.h56
-rw-r--r--drivers/media/isdbt/fc8100/fci_types.h46
-rw-r--r--drivers/media/isdbt/isdbt.c598
-rw-r--r--drivers/media/isdbt/isdbt.h26
29 files changed, 3654 insertions, 0 deletions
diff --git a/drivers/media/isdbt/Kconfig b/drivers/media/isdbt/Kconfig
new file mode 100644
index 0000000..59fb2fe
--- /dev/null
+++ b/drivers/media/isdbt/Kconfig
@@ -0,0 +1,5 @@
+config ISDBT_FC8100
+ boolean "ISDBT - DRIVER FC8100"
+ default n
+ ---help---
+ Isdbt driver for fci8100
diff --git a/drivers/media/isdbt/Makefile b/drivers/media/isdbt/Makefile
new file mode 100644
index 0000000..7cb1783
--- /dev/null
+++ b/drivers/media/isdbt/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the kernel character device drivers.
+#
+
+
+#obj-$(CONFIG_ISDBT_FC8100) += isdbt.o
+obj-$(CONFIG_ISDBT_FC8100) += fc8100/
diff --git a/drivers/media/isdbt/fc8100/KLlist.c b/drivers/media/isdbt/fc8100/KLlist.c
new file mode 100644
index 0000000..29ace3d
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/KLlist.c
@@ -0,0 +1,285 @@
+#include "LKlist.h"
+
+position LKAdvanceList(listptr alist)
+ /* Move current to the succeeding element. */
+{
+ if (alist->current) {
+ if (alist->icurrent == alist->n)
+ alist->icurrent = 1;
+ else
+ ++alist->icurrent;
+ }
+ alist->current = alist->current->next;
+ return((int)alist->current);
+}
+
+
+position LKReverseList(listptr alist) /* Move current to the preceeding element. */
+{
+ if (alist->current) {
+ if (alist->icurrent == 1)
+ alist->icurrent = alist->n;
+ else
+ --alist->icurrent;
+ }
+ alist->current = alist->current->prior;
+ return((int)alist->current);
+}
+
+
+position LKGotoInList(listptr alist, position i)
+ /* Set current to the ith list element. */
+{
+ position k;
+
+ alist->current = alist->head;
+ /* Closer to the tail or head? */
+ if ((i - 1) < (alist->n - i)) {
+/* Head : traverse forward. */
+ for (k = 1; k <= i - 1; k++)
+ alist->current = alist->current->next;
+ } else {
+/* Tail : traverse backward. */
+ for (k = alist->n; k >= i; k--)
+ alist->current = alist->current->prior;
+ }
+
+ alist->icurrent = i;
+ return((int)alist->current);
+}
+
+
+void LKGetFromList(listptr alist, position i, void *data)
+/* Retrieve the current list element from the list into data. */
+{
+ if (i <= alist->n) {
+ LKGotoInList(alist, i);
+#if 0
+ memmove(data, alist->current->data, alist->elSize);
+#else
+ data = alist->current->data;
+#endif
+
+ }
+ return;
+}
+
+
+void LKPutInList(listptr alist, position i, void *data)
+/* Update the current list element with data */
+{
+ if (i <= alist->n) {
+ LKGotoInList(alist, i);
+ memmove(alist->current->data, data, alist->elSize);
+ }
+ return;
+}
+
+
+position LKSearchList(listptr alist, void *data)
+{
+ int i;
+ int a, b;
+
+ a = data;
+
+ LKGotoInList(alist, 1);
+ for (i = 0; i < (alist->n); i++) {
+ b = alist->current->data;
+
+ if (b == a)
+ return alist->icurrent;
+
+ LKAdvanceList(alist);
+ }
+
+ if (alist->icurrent == 1)
+ return 0;
+}
+
+int LKInsertAfterInList(listptr alist, position i, void *data)
+/* Inserts a new list element following the current element. */
+{
+ nodeptr p;
+
+ if ((alist->head == NULL) || (i <= alist->n)) {
+ if ((p = malloc(sizeof(listnode))) == NULL) {
+ fprintf(stderr, "list.c: LKInsertAfterInList: malloc() [1] failed\n");
+ return(-1);
+ } else {
+#if 0
+ if ((p->data = (void *) malloc(alist->elSize)) == NULL) {
+ fprintf(stderr, "list.c: LKInsertAfterInList: malloc() [2] failed\n");
+ return(-1);
+ } else
+#endif
+ {
+#if 0
+ memmove(p->data, data, alist->elSize);
+#else
+ p->data = data;
+#endif
+ if (alist->head == NULL) {
+/* Empty list. */
+ alist->head = p;
+ alist->icurrent = 1;
+ p->next = p;
+ p->prior = p;
+ } else { /* Adjust the linkage */
+ LKGotoInList(alist, i);
+ alist->current->next->prior = p;
+ p->next = alist->current->next;
+ p->prior = alist->current;
+ alist->current->next = p;
+ ++alist->icurrent;
+ }
+ alist->current = p;
+ ++alist->n;
+ }
+ }
+ }
+ return(1);
+}
+
+int LKInsertBeforeInList(listptr alist, position i, void *data)
+/* Inserts a new list element preceeding the current element. */
+{
+ int result = 0;
+
+ if ((alist->head == NULL) || (i <= alist->n)) {
+/* Is list not empty? */
+ if (alist->head != NULL) {
+ LKGotoInList(alist, i);
+ alist->current = alist->current->prior;
+ --alist->icurrent;
+ if (alist->icurrent == 0) { /* check for head */
+ alist->icurrent = alist->n;
+ }
+ }
+ result = LKInsertAfterInList(alist, alist->icurrent, data);
+ /* used to be i not alist->icurrent */
+
+ if (alist->current->next == alist->head) {
+ /* Is insertion at list head? */
+ alist->head = alist->current;
+ alist->icurrent = 1;
+ }
+ }
+ return(result);
+}
+
+
+void LKDeleteFromList(listptr alist, position i)
+/* Delete the current element. */
+{
+ nodeptr precurrent;
+
+ if ((alist->head != NULL) & (i <= alist->n)) {
+ LKGotoInList(alist, i);
+ precurrent = alist->current;
+
+
+/* Relink list to exclude the node to be deleted. */
+ alist->current->prior->next = alist->current->next;
+ alist->current->next->prior = alist->current->prior;
+
+ /* Is tail node to be deleted? */
+
+ if (precurrent->next == alist->head)
+ alist->icurrent = 1;
+ alist->current = alist->current->next;
+ if (alist->n == 1) {
+ alist->head = NULL;
+ } else if (alist->head == precurrent) {
+ alist->head = alist->current;
+ }
+ --alist->n;
+#if 0
+ free(precurrent->data);
+#endif
+ free(precurrent);
+ precurrent = NULL;
+ }
+ return;
+}
+
+
+position LKCurrent(listptr alist)
+ /* Return the position of current. */
+{
+ return(alist->icurrent);
+}
+
+
+position LKLastInList(listptr alist)
+ /* Return the current list size. */
+{
+ return(alist->n);
+}
+
+
+int LKCreateList(linklist, space)
+ /* Initialize package before first use. */
+ listptr *linklist;
+ position space;
+{
+ listptr alist;
+ if ((alist = (listptr) malloc(sizeof(list))) == NULL) {
+ fprintf(stderr, "list.c: LKCreateList: malloc() failed\n");
+ return(-1);
+ } else {
+ alist->head = NULL;
+ alist->current = NULL;
+ alist->n = 0;
+ alist->icurrent = 0;
+ alist->elSize = space;
+ *linklist = alist;
+ }
+ return(1);
+}
+
+void LKClearList(listptr alist)
+ /* Reset the list to empty. */
+{
+ nodeptr prehead, q;
+
+ prehead = alist->head;
+/* Is the list not empty? */
+ if (alist->head != NULL) {
+ do {
+ q = alist->head;
+ alist->head = alist->head->next;
+ free(q->data);
+ free(q);
+ } while (alist->head != prehead);
+ }
+
+ /* Reinitialize the list. */
+ alist->head = NULL;
+ alist->current = NULL;
+ alist->n = 0;
+ alist->icurrent = 0;
+ return;
+}
+
+
+int LKEmptyList(listptr alist)
+ /* Is the list Empty? */
+{
+ if (alist->head == NULL) {
+ return((int) NULL);
+ }
+ return 1;
+}
+
+
+
+void LKZapList(listptr *alist)
+ /* Reset the list to empty. */
+{
+
+ LKClearList(*alist);
+ free(*alist);
+ *alist = NULL;
+ return;
+}
diff --git a/drivers/media/isdbt/fc8100/LKlist.h b/drivers/media/isdbt/fc8100/LKlist.h
new file mode 100644
index 0000000..b895866
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/LKlist.h
@@ -0,0 +1,44 @@
+#ifndef LKLIST_INC
+#define LKLIST_INC
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+typedef int position;
+
+typedef struct node *nodeptr;
+typedef struct node {
+ void *data;
+ nodeptr next;
+ nodeptr prior;
+} listnode;
+
+typedef struct listrec *listptr;
+typedef struct listrec {
+ nodeptr head;
+ nodeptr current;
+ position elSize;
+ position n;
+ position icurrent;
+} list;
+
+position LKAdvanceList(listptr);
+void LKClearList(listptr);
+int LKCreateList(listptr*, position);
+position LKCurrent(listptr);
+void LKDeleteFromList(listptr, position);
+int LKEmptyList(listptr);
+void LKGetFromList(listptr, position, void *);
+position LKGotoInList(listptr, position);
+int LKInsertAfterInList(listptr, position, void *);
+int LKInsertBeforeInList(listptr, position, void *);
+position LKSearchList(listptr, void *);
+position LKLastInList(listptr);
+void LKPutInList(listptr, position, void *);
+position LKReverseList(listptr);
+void LKZapList(listptr *);
+
+
+#endif
+/* LKLIST_INC */
diff --git a/drivers/media/isdbt/fc8100/Makefile b/drivers/media/isdbt/fc8100/Makefile
new file mode 100644
index 0000000..c525531
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/Makefile
@@ -0,0 +1,16 @@
+#fci driver
+
+obj-$(CONFIG_ISDBT_FC8100) := isdbt.o
+isdbt-objs := fc8100.o bbm.o fc8100_bb.o fci_tun.o fci_hal.o fci_i2c.o fc8100_isr.o fc8100_tun.o fc8100_i2c.o fci_oal.o
+
+#KDIR := /home/android/workspace/S5PC100/kernel
+#KDIR := /usr/src/linux-headers-2.6.31-14-generic
+PWD := $(shell pwd)
+
+all:
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
+clean:
+ rm -rf *.ko
+ rm -rf *.mod.*
+ rm -rf .*.cmd
+ rm -rf *.o
diff --git a/drivers/media/isdbt/fc8100/bbm.c b/drivers/media/isdbt/fc8100/bbm.c
new file mode 100644
index 0000000..c171281
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/bbm.c
@@ -0,0 +1,237 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : bbm.c
+
+ Description : API of dmb baseband module
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/11/28 jason initial
+*******************************************************************************/
+
+#include "fci_types.h"
+#include "fci_oal.h"
+#include "fci_hal.h"
+#include "fci_tun.h"
+#include "fc8100_bb.h"
+#include "fc8100_isr.h"
+
+int BBM_RESET(HANDLE hDevice)
+{
+ int res;
+
+ res = fc8100_reset(hDevice);
+
+ return res;
+}
+
+int BBM_PROBE(HANDLE hDevice)
+{
+ int res;
+
+ res = fc8100_probe(hDevice);
+
+ return res;
+}
+
+int BBM_INIT(HANDLE hDevice)
+{
+ int res;
+
+ res = fc8100_init(hDevice);
+
+ return res;
+}
+
+int BBM_DEINIT(HANDLE hDevice)
+{
+ int res;
+
+ res = fc8100_deinit(hDevice);
+
+ return res;
+}
+
+int BBM_READ(HANDLE hDevice, u16 addr, u8 *data)
+{
+ int res;
+
+ res = bbm_read(hDevice, addr, data);
+
+ return res;
+}
+
+int BBM_BYTE_READ(HANDLE hDevice, u16 addr, u8 *data)
+{
+ int res;
+
+ res = bbm_byte_read(hDevice, addr, data);
+
+ return res;
+}
+
+int BBM_WORD_READ(HANDLE hDevice, u16 addr, u16 *data)
+{
+ int res;
+
+ res = bbm_word_read(hDevice, addr, data);
+
+ return res;
+}
+
+int BBM_LONG_READ(HANDLE hDevice, u16 addr, u32 *data)
+{
+ int res;
+
+ res = bbm_long_read(hDevice, addr, data);
+
+ return BBM_OK;
+}
+
+int BBM_BULK_READ(HANDLE hDevice, u16 addr, u8 *data, u16 size)
+{
+ int res;
+
+ res = bbm_bulk_read(hDevice, addr, data, size);
+
+ return res;
+}
+
+int BBM_WRITE(HANDLE hDevice, u16 addr, u8 data)
+{
+ int res;
+
+ res = bbm_write(hDevice, addr, data);
+
+ return res;
+}
+
+int BBM_BYTE_WRITE(HANDLE hDevice, u16 addr, u8 data)
+{
+ int res;
+
+ res = bbm_byte_write(hDevice, addr, data);
+
+ return res;
+}
+
+int BBM_WORD_WRITE(HANDLE hDevice, u16 addr, u16 data)
+{
+ int res;
+
+ res = bbm_word_write(hDevice, addr, data);
+
+ return res;
+}
+
+int BBM_LONG_WRITE(HANDLE hDevice, u16 addr, u32 data)
+{
+ int res;
+
+ res = bbm_long_write(hDevice, addr, data);
+
+ return res;
+}
+
+int BBM_BULK_WRITE(HANDLE hDevice, u16 addr, u8 *data, u16 size)
+{
+ int res;
+
+ res = bbm_bulk_write(hDevice, addr, data, size);
+
+ return res;
+}
+
+int BBM_TUNER_READ(HANDLE hDevice, u8 addr, u8 alen, u8 *buffer, u8 len)
+{
+ int res;
+
+ res = tuner_i2c_read(hDevice, addr, alen, buffer, len);
+
+ return res;
+}
+
+int BBM_TUNER_WRITE(HANDLE hDevice, u8 addr, u8 alen, u8 *buffer, u8 len)
+{
+ int res;
+
+ res = tuner_i2c_write(hDevice, addr, alen, buffer, len);
+
+ return res;
+}
+
+int BBM_TUNER_SET_FREQ(HANDLE hDevice, u8 ch_num)
+{
+ int res = BBM_OK;
+
+ res = tuner_set_freq(hDevice, ch_num);
+
+ return res;
+}
+
+int BBM_TUNER_GET_RSSI(HANDLE hDevice, s32 *rssi)
+{
+ int res = BBM_OK;
+
+ res = tuner_get_rssi(hDevice, rssi);
+
+ return res;
+}
+
+int BBM_TUNER_SELECT(HANDLE hDevice, u32 product, u32 band)
+{
+ int res = BBM_OK;
+
+ res = tuner_select(hDevice, product, band);
+
+ return res;
+}
+
+int BBM_TUNER_DESELECT(HANDLE hDevice)
+{
+ int res = BBM_OK;
+
+ res = tuner_deselect(hDevice);
+
+ return res;
+}
+
+int BBM_HOSTIF_SELECT(HANDLE hDevice, u8 hostif)
+{
+ int res = BBM_NOK;
+
+ res = bbm_hostif_select(hDevice, hostif);
+
+ return res;
+}
+
+int BBM_HOSTIF_DESELECT(HANDLE hDevice)
+{
+ int res = BBM_NOK;
+
+ res = bbm_hostif_deselect(hDevice);
+
+ return res;
+}
+
+int BBM_CALLBACK_REGISTER(u32 userdata, int (*callback)(u32 userdata, u8 *data, int length))
+{
+ gUserData = userdata;
+ pCallback = callback;
+
+ return BBM_OK;
+}
+
+int BBM_CALLBACK_DEREGISTER(HANDLE hDevice)
+{
+ gUserData = 0;
+ pCallback = NULL;
+
+ return BBM_OK;
+}
+
+void BBM_ISR(HANDLE hDevice)
+{
+ fc8100_isr(hDevice);
+}
diff --git a/drivers/media/isdbt/fc8100/bbm.h b/drivers/media/isdbt/fc8100/bbm.h
new file mode 100644
index 0000000..a2a0cac
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/bbm.h
@@ -0,0 +1,61 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : bbm.h
+
+ Description : API of dmb baseband module
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/08/29 jason initial
+*******************************************************************************/
+
+#ifndef __BBM_H__
+#define __BBM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DRIVER_VER "VER 1.0"
+
+#define BBM_HPI 0 /* EBI2 */
+#define BBM_SPI 1 /* SPI */
+#define BBM_I2C 2 /* I2C+TSIF */
+
+extern int BBM_RESET(HANDLE hDevice);
+extern int BBM_PROBE(HANDLE hDevice);
+extern int BBM_INIT(HANDLE hDevice);
+extern int BBM_DEINIT(HANDLE hDevice);
+
+extern int BBM_READ(HANDLE hDevice, u16 addr, u8 *data);
+extern int BBM_BYTE_READ(HANDLE hDevice, u16 addr, u8 *data);
+extern int BBM_WORD_READ(HANDLE hDevice, u16 addr, u16 *data);
+extern int BBM_LONG_READ(HANDLE hDevice, u16 addr, u32 *data);
+extern int BBM_BULK_READ(HANDLE hDevice, u16 addr, u8 *data, u16 size);
+extern int BBM_WRITE(HANDLE hDevice, u16 addr, u8 data);
+extern int BBM_BYTE_WRITE(HANDLE hDevice, u16 addr, u8 data);
+extern int BBM_WORD_WRITE(HANDLE hDevice, u16 addr, u16 data);
+extern int BBM_LONG_WRITE(HANDLE hDevice, u16 addr, u32 data);
+extern int BBM_BULK_WRITE(HANDLE hDevice, u16 addr, u8 *data, u16 size);
+
+extern int BBM_TUNER_READ(HANDLE hDevice, u8 addr, u8 alen, u8 *buffer, u8 len);
+extern int BBM_TUNER_WRITE(HANDLE hDevice, u8 addr, u8 alen, u8 *buffer, u8 len);
+extern int BBM_TUNER_SET_FREQ(HANDLE hDevice, u8 ch_num);
+extern int BBM_TUNER_GET_RSSI(HANDLE hDevice, s32 *rssi);
+extern int BBM_TUNER_SELECT(HANDLE hDevice, u32 product, u32 band);
+extern int BBM_TUNER_DESELECT(HANDLE hDevice);
+
+extern void BBM_ISR(HANDLE hDevice);
+
+extern int BBM_HOSTIF_SELECT(HANDLE hDevice, u8 hostif);
+extern int BBM_HOSTIF_DESELECT(HANDLE hDevice);
+
+extern int BBM_CALLBACK_REGISTER(u32 userdata, int (*callback)(u32 userdata, u8 *data, int length));
+extern int BBM_CALLBACK_DEREGISTER(HANDLE hDevice);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BBM_H__ */
diff --git a/drivers/media/isdbt/fc8100/fc8100.c b/drivers/media/isdbt/fc8100/fc8100.c
new file mode 100644
index 0000000..1d4a7a3
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100.c
@@ -0,0 +1,271 @@
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/miscdevice.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-core.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+
+#include "fc8100.h"
+#include "bbm.h"
+#include "fci_oal.h"
+
+#define FC8100_NAME "isdbt"
+
+int dmb_open (struct inode *inode, struct file *filp);
+loff_t dmb_llseek (struct file *filp, loff_t off, int whence);
+ssize_t dmb_read (struct file *filp, char *buf, size_t count, loff_t *f_pos);
+ssize_t dmb_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos);
+static long dmb_ioctl (struct file *filp, unsigned int cmd, unsigned long arg);
+int dmb_release (struct inode *inode, struct file *filp);
+
+/* GPIO Setting */
+void dmb_hw_setting(void);
+void dmb_hw_init(void);
+void dmb_hw_deinit(void);
+
+static struct file_operations dmb_fops = {
+ .owner = THIS_MODULE,
+ .llseek = dmb_llseek,
+ .read = dmb_read,
+ .write = dmb_write,
+ .unlocked_ioctl = dmb_ioctl,
+ .open = dmb_open,
+ .release = dmb_release,
+};
+
+static struct miscdevice fc8100_misc_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = FC8100_NAME,
+ .fops = &dmb_fops,
+};
+
+int dmb_open (struct inode *inode, struct file *filp)
+{
+ int num = MINOR(inode->i_rdev);
+
+ /* ISDBT PWR ENABLE FOR I2C*/
+ dmb_hw_setting();
+ dmb_hw_init();
+
+ PRINTF(0, "dmb open -> minor : %d\n", num);
+
+ return 0;
+}
+
+loff_t dmb_llseek (struct file *filp, loff_t off, int whence)
+{
+ PRINTF(0, "dmb llseek -> off : %08X, whence : %08X\n", off, whence);
+ return 0x23;
+}
+
+ssize_t dmb_read (struct file *filp, char *buf, size_t count, loff_t *f_pos)
+{
+ PRINTF(0, "dmb read -> buf : %08X, count : %08X \n", buf, count);
+ return 0x33;
+}
+
+ssize_t dmb_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos)
+{
+ PRINTF(0, "dmb write -> buf : %08X, count : %08X \n", buf, count);
+ return 0x43;
+}
+
+static long dmb_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ s32 res = BBM_NOK;
+ int status = 0;
+ int status_usr = 0;
+ ioctl_info info;
+ int size;
+
+ if (_IOC_TYPE(cmd) != IOCTL_MAGIC)
+ return -EINVAL;
+ if (_IOC_NR(cmd) >= IOCTL_MAXNR)
+ return -EINVAL;
+
+ size = _IOC_SIZE(cmd);
+
+ switch (cmd) {
+ case IOCTL_DMB_RESET:
+ res = BBM_RESET(0);
+ break;
+ case IOCTL_DMB_INIT:
+ res = BBM_INIT(0);
+ break;
+ case IOCTL_DMB_BYTE_READ:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_BYTE_READ(0, (u16)info.buff[0], (u8 *)(&info.buff[1]));
+ status_usr = copy_to_user((void *)arg, (void *)&info, size);
+ break;
+ case IOCTL_DMB_WORD_READ:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_WORD_READ(0, (u16)info.buff[0], (u16 *)(&info.buff[1]));
+ status_usr = copy_to_user((void *)arg, (void *)&info, size);
+ break;
+ case IOCTL_DMB_LONG_READ:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_LONG_READ(0, (u16)info.buff[0], (u32 *)(&info.buff[1]));
+ status_usr = copy_to_user((void *)arg, (void *)&info, size);
+ break;
+ case IOCTL_DMB_BULK_READ:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_BULK_READ(0, (u16)info.buff[0], (u8 *)(&info.buff[2]), info.buff[1]);
+ status_usr = copy_to_user((void *)arg, (void *)&info, size);
+ break;
+ case IOCTL_DMB_BYTE_WRITE:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_BYTE_WRITE(0, (u16)info.buff[0], (u8)info.buff[1]);
+ break;
+ case IOCTL_DMB_WORD_WRITE:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_WORD_WRITE(0, (u16)info.buff[0], (u16)info.buff[1]);
+ break;
+ case IOCTL_DMB_LONG_WRITE:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_LONG_WRITE(0, (u16)info.buff[0], (u32)info.buff[1]);
+ break;
+ case IOCTL_DMB_BULK_WRITE:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_BULK_WRITE(0, (u16)info.buff[0], (u8 *)(&info.buff[2]), info.buff[1]);
+ break;
+ case IOCTL_DMB_TUNER_SELECT:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_TUNER_SELECT(0, (u32)info.buff[0], 0);
+ break;
+ case IOCTL_DMB_TUNER_READ:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_TUNER_READ(0, (u8)info.buff[0], (u8)info.buff[1], (u8 *)(&info.buff[3]), (u8)info.buff[2]);
+ status_usr = copy_to_user((void *)arg, (void *)&info, size);
+ break;
+ case IOCTL_DMB_TUNER_WRITE:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_TUNER_WRITE(0, (u8)info.buff[0], (u8)info.buff[1], (u8 *)(&info.buff[3]), (u8)info.buff[2]);
+ break;
+ case IOCTL_DMB_TUNER_SET_FREQ:
+ status = copy_from_user((void *)&info, (void *)arg, size);
+ res = BBM_TUNER_SET_FREQ(0, (u8)info.buff[0]);
+ break;
+ case IOCTL_DMB_POWER_ON:
+ PRINTF(0, "DMB_POWER_ON enter..\n");
+ dmb_hw_init();
+ break;
+ case IOCTL_DMB_POWER_OFF:
+ PRINTF(0, "DMB_POWER_OFF enter..\n");
+ dmb_hw_deinit();
+ break;
+ }
+ if ((status < 0) || (status_usr < 0)) {
+ PRINTF(0, " copy to user or copy from user : ERROR..\n");
+ return -EINVAL;
+ }
+
+ /* return status */
+ if (res < 0)
+ res = -BBM_NOK;
+ else
+ res = BBM_OK;
+
+ return res;
+}
+
+int dmb_release(struct inode *inode, struct file *filp)
+{
+ /* ISDBT PWR ENABLE FOR I2C*/
+ PRINTF(0, "dmb release\n");
+ return 0;
+}
+
+void dmb_hw_setting(void)
+{
+ s3c_gpio_cfgpin(GPIO_ISDBT_SDA_28V, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_ISDBT_SDA_28V, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_ISDBT_SCL_28V, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_ISDBT_SCL_28V, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_ISDBT_PWR_EN, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_ISDBT_PWR_EN, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_ISDBT_RST, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_ISDBT_RST, GPIO_LEVEL_HIGH);
+}
+
+void dmb_init_hw_setting(void)
+{
+ s3c_gpio_cfgpin(GPIO_ISDBT_SDA_28V, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_ISDBT_SDA_28V, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_ISDBT_SCL_28V, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_ISDBT_SCL_28V, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_ISDBT_PWR_EN, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_ISDBT_PWR_EN, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_ISDBT_RST, S3C_GPIO_OUTPUT);
+ gpio_set_value(GPIO_ISDBT_RST, GPIO_LEVEL_LOW);
+}
+
+void dmb_hw_init(void)
+{
+ mdelay(1);
+ gpio_set_value(GPIO_ISDBT_PWR_EN, GPIO_LEVEL_HIGH);
+ mdelay(1);
+ gpio_set_value(GPIO_ISDBT_RST, GPIO_LEVEL_HIGH);
+ mdelay(100);
+}
+
+void dmb_hw_deinit(void)
+{
+ mdelay(1);
+ gpio_set_value(GPIO_ISDBT_RST, GPIO_LEVEL_LOW);
+ mdelay(1);
+ gpio_set_value(GPIO_ISDBT_PWR_EN, GPIO_LEVEL_LOW);
+ mdelay(100);
+}
+
+
+int dmb_init(void)
+{
+ int result;
+
+ PRINTF(0, "dmb dmb_init\n");
+
+ dmb_init_hw_setting();
+/*
+ dmb_hw_init();
+*/
+ /*misc device registration*/
+ result = misc_register(&fc8100_misc_device);
+
+ if (result < 0)
+ return result;
+
+ BBM_HOSTIF_SELECT(0, BBM_I2C);
+
+ dmb_hw_deinit();
+
+ return 0;
+}
+
+void dmb_exit(void)
+{
+ PRINTF(0, "dmb dmb_exit\n");
+
+ BBM_HOSTIF_DESELECT(0);
+ dmb_hw_deinit();
+
+ /*misc device deregistration*/
+ misc_deregister(&fc8100_misc_device);
+}
+
+module_init(dmb_init);
+module_exit(dmb_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/media/isdbt/fc8100/fc8100.h b/drivers/media/isdbt/fc8100/fc8100.h
new file mode 100644
index 0000000..ceffe83
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100.h
@@ -0,0 +1,66 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : bbm.c
+
+ Description : API of dmb baseband module
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/08/29 jason initial
+*******************************************************************************/
+
+#ifndef __DMB_H__
+#define __DMB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "fci_types.h"
+
+#define MAX_OPEN_NUM 8
+
+#define IOCTL_MAGIC 't'
+
+typedef struct {
+ unsigned long size;
+ unsigned long buff[128];
+} ioctl_info;
+
+#define IOCTL_MAXNR 22
+
+#define IOCTL_DMB_RESET _IO(IOCTL_MAGIC, 0)
+#define IOCTL_DMB_PROBE _IO(IOCTL_MAGIC, 1)
+#define IOCTL_DMB_INIT _IO(IOCTL_MAGIC, 2)
+#define IOCTL_DMB_DEINIT _IO(IOCTL_MAGIC, 3)
+
+#define IOCTL_DMB_BYTE_READ _IOWR(IOCTL_MAGIC, 4, ioctl_info)
+#define IOCTL_DMB_WORD_READ _IOWR(IOCTL_MAGIC, 5, ioctl_info)
+#define IOCTL_DMB_LONG_READ _IOWR(IOCTL_MAGIC, 6, ioctl_info)
+#define IOCTL_DMB_BULK_READ _IOWR(IOCTL_MAGIC, 7, ioctl_info)
+
+#define IOCTL_DMB_BYTE_WRITE _IOW(IOCTL_MAGIC, 8, ioctl_info)
+#define IOCTL_DMB_WORD_WRITE _IOW(IOCTL_MAGIC, 9, ioctl_info)
+#define IOCTL_DMB_LONG_WRITE _IOW(IOCTL_MAGIC, 10, ioctl_info)
+#define IOCTL_DMB_BULK_WRITE _IOW(IOCTL_MAGIC, 11, ioctl_info)
+
+#define IOCTL_DMB_TUNER_READ _IOWR(IOCTL_MAGIC, 12, ioctl_info)
+#define IOCTL_DMB_TUNER_WRITE _IOW(IOCTL_MAGIC, 13, ioctl_info)
+
+#define IOCTL_DMB_TUNER_SET_FREQ _IOW(IOCTL_MAGIC, 14, ioctl_info)
+#define IOCTL_DMB_TUNER_SELECT _IOW(IOCTL_MAGIC, 15, ioctl_info)
+#define IOCTL_DMB_TUNER_DESELECT _IO(IOCTL_MAGIC, 16)
+#define IOCTL_DMB_TUNER_GET_RSSI _IOWR(IOCTL_MAGIC, 17, ioctl_info)
+
+#define IOCTL_DMB_HOSTIF_SELECT _IOW(IOCTL_MAGIC, 18, ioctl_info)
+#define IOCTL_DMB_HOSTIF_DESELECT _IO(IOCTL_MAGIC, 19)
+
+#define IOCTL_DMB_POWER_ON _IO(IOCTL_MAGIC, 20)
+#define IOCTL_DMB_POWER_OFF _IO(IOCTL_MAGIC, 21)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/fc8100/fc8100_bb.c b/drivers/media/isdbt/fc8100/fc8100_bb.c
new file mode 100644
index 0000000..4e18ff7
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100_bb.c
@@ -0,0 +1,204 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8100_bb.c
+
+ Description : API of dmb baseband module
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/09/29 bruce initial
+*******************************************************************************/
+#include "fci_types.h"
+#include "fci_oal.h"
+#include "fc8100_regs.h"
+#include "fci_hal.h"
+
+#define BB_SW_RESET_USE 1 /* 0: NOT USE 1. USE */
+
+/*
+select BB Xtal frequency
+16Mhz: 16000 18Mhz:18000 19.2Mhz:19200 24Mhz:24000
+26Mhz:26000 32Mhz:32000 40Mhz:40000
+*/
+#define FC8100_FREQ_XTAL_BB 26000
+
+static int fc8100_bb_pll_set(HANDLE hDevice, u32 xtal)
+{
+ int res = BBM_NOK;
+
+ if (BB_SW_RESET_USE) {
+ res = bbm_write(hDevice, BBM_SYSRST, 0x01); /* System Reset */
+ if (res)
+ return res;
+ msWait(10);
+ }
+
+ switch (xtal) {
+ case 16000:
+ res = bbm_write(hDevice, BBM_PLL0 , 0x0F); /* PLL 16MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL1, 0x50); /* PLL 16MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL2, 0xBF); /* PLL 16MHz Setting */
+ break;
+ case 18000:
+ res = bbm_write(hDevice, BBM_PLL0, 0x11); /* PLL 18MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL1, 0x50); /* PLL 18MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL2, 0xBF); /* PLL 18MHz Setting */
+ break;
+ case 19200:
+ res = bbm_write(hDevice, BBM_PLL0, 0x09); /* PLL 19.2MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL1, 0x50); /* PLL 19.2MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL2, 0x63); /* PLL 19.2MHz Setting */
+ break;
+ case 24000:
+ res = bbm_write(hDevice, BBM_PLL0, 0x17); /* PLL 24MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL1, 0x50); /* PLL 24MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL2, 0xBF); /* PLL 24MHz Setting */
+ break;
+ case 26000:
+ res = bbm_write(hDevice, BBM_PLL0, 0x19); /* PLL 26MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL1, 0x50); /* PLL 26MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL2, 0xBF); /* PLL 26MHz Setting */
+ break;
+ case 32000:
+ res = bbm_write(hDevice, BBM_PLL0, 0x1F); /* PLL 32MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL1, 0x50); /* PLL 32MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL2, 0xBF); /* PLL 32MHz Setting */
+ break;
+ case 40000:
+ res = bbm_write(hDevice, BBM_PLL0, 0x27); /* PLL 40MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL1, 0x30); /* PLL 40MHz Setting */
+ res |= bbm_write(hDevice, BBM_PLL2, 0x9F); /* PLL 40MHz Setting */
+ break;
+ default:
+ return BBM_NOK;
+ break;
+ }
+
+ return res;
+}
+
+static int fc8100_ofdm_Init(HANDLE hDevice)
+{
+ int res = BBM_NOK;
+#if defined(CONFIG_VIDEO_TSI)
+ /* General Setting */
+ res = bbm_write(hDevice,BBM_INCTRL, 0x03); // IF Low injenction
+ res |= bbm_write(hDevice,BBM_OUTCTRL0 , 0x28); // TS Setting 0x28
+ res |= bbm_write(hDevice,BBM_OUTCTRL1, 0x11); // TS Serial Out
+ res |= bbm_write(hDevice,BBM_GPIOSEL1, 0xA0); // PCKETERR, LOCK out
+ res |= bbm_write(hDevice,BBM_RSEPER, BER_PACKET_SIZE); // BER counter update period @ 256 TSP
+ res |= bbm_write(hDevice,BBM_RSERST, 0x01); // reset for BER counter change
+ res |= bbm_write(hDevice,BBM_THRURS, 0x00); // Pst-Rs
+#else
+ /* General Setting */
+ res = bbm_write(hDevice, BBM_INCTRL, 0x03); /* IF Low injenction */
+ /*
+ data clock always on : 0x28
+ data clock vaild pkt on : 0x2D
+ fci default : 0x28
+ modify for c210_spi : 0x2D
+ */
+ res |= bbm_write(hDevice, BBM_OUTCTRL0 , 0x2D); /* TS Setting 0x28 */
+
+ /* cs active low :0x12
+ cs active high :0x10
+ fci default : 0x10
+ modify for c210_spi(only active low) : 0x12
+ */
+ res |= bbm_write(hDevice, BBM_OUTCTRL1, 0x12); /* TS Serial Out */
+ res |= bbm_write(hDevice, BBM_GPIOSEL1, 0xA0); /* PCKETERR, LOCK out */
+ res |= bbm_write(hDevice, BBM_RSEPER, BER_PACKET_SIZE); /* BER counter update period @ 256 TSP */
+ res |= bbm_write(hDevice, BBM_RSERST, 0x01); /* reset for BER counter change */
+ res |= bbm_write(hDevice, BBM_THRURS, 0x00); /* Pst-Rs */
+#endif
+ /* AGC */
+ res |= bbm_write(hDevice, BBM_AGTIME, 0x0E); /* Sync. Speed */
+ res |= bbm_write(hDevice, BBM_AGREF1, 0x40); /* Sensitivity */
+
+ /* Digital AGC Setting */
+ res |= bbm_write(hDevice, BBM_DAM3REF0, 0x00); /* multipath measure */
+ res |= bbm_write(hDevice, BBM_DAM3REF1, 0x80); /* multipath measure */
+ res |= bbm_write(hDevice, BBM_DALPG, 0x01); /* Shadowing */
+
+ /* Sync. */
+ res |= bbm_write(hDevice, BBM_SYATTH, 0x58); /*Sync. Speed */
+ res |= bbm_write(hDevice, BBM_SYSW2, 0x4E); /* Move Ini. Window Pos. (64point) */
+
+ /* TMCC */
+ res |= bbm_write(hDevice, BBM_TMCTRL1, 0xEB); /* Sync. Speed ([7:5] default) */
+ res |= bbm_write(hDevice, BBM_TMCTRL2, 0x60); /* Avoid Count Down Error */
+
+ /* CF Setting */
+ res |= bbm_write(hDevice, BBM_FTCTRL, 0x33); /* TU6 & Multipath */
+ res |= bbm_write(hDevice, BBM_EQCONF, 0x08); /* Sensitivity */
+
+ /* De-Noise Filter */
+ res |= bbm_write(hDevice, BBM_EQCTRL, 0x14); /* DNF Ini Setting */
+ res |= bbm_write(hDevice, BBM_GNFCNT1, 0xE4); /* DNF On/Off Setting */
+ res |= bbm_write(hDevice, BBM_WINPTMN, 0x09); /* 12point from Symbol Head */
+ res |= bbm_write(hDevice, BBM_IFCTRL, 0x11); /* for Clip */
+
+ /* Window Position for 2path Raylength */
+ res |= bbm_write(hDevice, BBM_WINCTRL1, 0x24); /* Window Position */
+ res |= bbm_write(hDevice, BBM_WINCTRL2_1, 0x42); /* move limit & timing */
+
+ /* GI */
+ res |= bbm_write(hDevice, BBM_GICCNT1, 0x77); /* m Up/Dn count slow */
+ res |= bbm_write(hDevice, BBM_WINTHTR, 0x0B); /* Pst-Ghost DU=5dB */
+ /* Ghost */
+ res |= bbm_write(hDevice, BBM_GNFSNTH, 0x04); /* Pst-Ghost 11dB */
+ res |= bbm_write(hDevice, BBM_GNFCNT2, 0x0A); /* Skip for 6path Multipath*/
+ res |= bbm_write(hDevice, BBM_WINCTRL, 0x35); /* Pre-Ghost 13dB */
+ res |= bbm_write(hDevice, BBM_IFUN, 0x02); /* Clp Off */
+
+ /* Switch Interpolation */
+ res |= bbm_write(hDevice, BBM_EQSI1, 0x3E); /* Fav with 512symbol */
+ res |= bbm_write(hDevice, BBM_EQSI2, 0x10); /* Threshold */
+
+ /* External LNA Control */
+ res |= bbm_write(hDevice, BBM_GPIOSEL0, 0x01);
+ res |= bbm_write(hDevice, BBM_AWCTRL, 0x2D);
+ res |= bbm_write(hDevice, BBM_AWONTH, 0x20); /* LNA On CNR = 9sB */
+ res |= bbm_write(hDevice, BBM_AWOFFTH, 0x10); /* LNA Off CNR+13dB */
+ res |= bbm_write(hDevice, BBM_AWAGCTH, 0x01);
+
+ res |= bbm_write(hDevice, BBM_SYSRST, 0x02); /* S/W Reset */
+
+ return res;
+}
+
+int fc8100_reset(HANDLE hDevice)
+{
+ int res = BBM_NOK;
+ res = bbm_write(hDevice, BBM_SYSRST, 0x02);
+ return res;
+}
+
+int fc8100_probe(HANDLE hDevice)
+{
+ int res = BBM_NOK;
+ u8 ver;
+
+ res = bbm_read(hDevice, BBM_VERSION, &ver);
+
+ if (ver != 0x41)
+ res = BBM_NOK ;
+
+ return res;
+}
+
+int fc8100_init(HANDLE hDevice)
+{
+ int res = BBM_NOK;
+
+ res = fc8100_bb_pll_set(hDevice, FC8100_FREQ_XTAL_BB);
+ res |= fc8100_ofdm_Init(hDevice);
+
+ return res;
+}
+
+int fc8100_deinit(HANDLE hDevice)
+{
+ return BBM_OK;
+}
diff --git a/drivers/media/isdbt/fc8100/fc8100_bb.h b/drivers/media/isdbt/fc8100/fc8100_bb.h
new file mode 100644
index 0000000..db7a414
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100_bb.h
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8100_bb.h
+
+ Description : baseband header file
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/09/29 bruce initial
+*******************************************************************************/
+
+#ifndef __FC8100_BB_H__
+#define __FC8100_BB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int fc8100_reset(HANDLE hDevice);
+extern int fc8100_probe(HANDLE hDevice);
+extern int fc8100_init(HANDLE hDevice);
+extern int fc8100_deinit(HANDLE hDevice);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/fc8100/fc8100_i2c.c b/drivers/media/isdbt/fc8100/fc8100_i2c.c
new file mode 100644
index 0000000..7f189f0
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100_i2c.c
@@ -0,0 +1,349 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8100_i2c.c
+
+ Description : fc8100 host interface
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/09/29 bruce initial
+*******************************************************************************/
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-core.h>
+#include <mach/regs-gpio.h>
+#include <mach/regs-clock.h>
+#include "fci_types.h"
+#include "fci_oal.h"
+
+#define FC8100_I2C_ADDR 0x77
+#define I2C_M_FCIRD 1
+#define I2C_M_FCIWR 0
+#define I2C_MAX_SEND_LENGTH 300
+
+struct i2c_ts_driver{
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct work_struct work;
+};
+
+struct i2c_client *fc8100_i2c;
+
+struct i2c_driver fc8100_i2c_driver;
+
+static int i2c_bb_read(HANDLE hDevice, u16 addr, u8 *data, u16 length);
+
+static int fc8100_i2c_probe(struct i2c_client *i2c_client,
+ const struct i2c_device_id *id)
+{
+ fc8100_i2c = i2c_client;
+ i2c_set_clientdata(i2c_client, NULL);
+
+ return 0;
+}
+
+static int fc8100_remove(struct i2c_client *client)
+{
+ return 0;
+}
+
+static const struct i2c_device_id fc8100_id[] = {
+ { "isdbti2c", 0 },
+ { },
+};
+
+struct i2c_driver fc8100_i2c_driver = {
+ .driver = {
+ .name = "fc8100_i2c",
+ .owner = THIS_MODULE,
+ },
+ .probe = fc8100_i2c_probe,
+ .remove = fc8100_remove,
+ .id_table = fc8100_id,
+};
+
+static int i2c_init(void)
+{
+ int res;
+
+ printk("fc8100_i2c_drv_init ENTER...\n");
+ fc8100_i2c = kzalloc(sizeof(struct i2c_ts_driver), GFP_KERNEL);
+
+ if (fc8100_i2c == NULL)
+ return -ENOMEM;
+
+ res = i2c_add_driver(&fc8100_i2c_driver);
+
+ return res;
+}
+
+static int i2c_deinit(void)
+{
+ printk("fc8100_i2c_drv_deinit ENTER...\n");
+
+ i2c_del_driver(&fc8100_i2c_driver);
+
+ return 0;
+}
+
+static int i2c_bb_read(HANDLE hDevice, u16 addr, u8 *data, u16 length)
+{
+ int res;
+ struct i2c_msg rmsg[2];
+ unsigned char i2c_data[1];
+
+ rmsg[0].addr = fc8100_i2c->addr;
+ rmsg[0].flags = I2C_M_FCIWR;
+ rmsg[0].len = 1;
+ rmsg[0].buf = i2c_data;
+ i2c_data[0] = addr & 0xff;
+
+ rmsg[1].addr = fc8100_i2c->addr;
+ rmsg[1].flags = I2C_M_FCIRD;
+ rmsg[1].len = length;
+ rmsg[1].buf = data;
+ res = i2c_transfer(fc8100_i2c->adapter, &rmsg[0], 2);
+
+ /* return status */
+ if (res >= 0)
+ res = 0;
+
+ return res;
+}
+
+static int i2c_bb_write(HANDLE hDevice, u16 addr, u8 *data, u16 length)
+{
+ int res;
+ struct i2c_msg wmsg;
+ unsigned char i2c_data[I2C_MAX_SEND_LENGTH];
+
+ if (length+1 > I2C_MAX_SEND_LENGTH) {
+ printk(".......error");
+ return -ENODEV;
+ }
+ wmsg.addr = fc8100_i2c->addr;
+ wmsg.flags = I2C_M_FCIWR;
+ wmsg.len = length + 1;
+ wmsg.buf = i2c_data;
+
+ i2c_data[0] = addr & 0xff;
+ memcpy(&i2c_data[1], data, length);
+
+ res = i2c_transfer(fc8100_i2c->adapter, &wmsg, 1);
+
+ /* return status */
+ if (res >= 0)
+ res = 0;
+
+ return res;
+}
+
+static int i2c_rf_read(HANDLE hDevice, u8 addr, u8 *data, u8 length)
+{
+ int res;
+ struct i2c_msg rmsg[3];
+ unsigned char i2c_rp_data[2];
+ unsigned char i2c_data[1];
+
+ /* printk("i2c_rf_read ENTER addr : %x, length : %d\n", addr, length); */
+ rmsg[0].addr = fc8100_i2c->addr;
+ rmsg[0].flags = I2C_M_FCIWR;
+ rmsg[0].len = 2;
+ rmsg[0].buf = i2c_rp_data;
+ i2c_rp_data[0] = 0x02;
+ i2c_rp_data[1] = 0x01;
+
+ rmsg[1].addr = fc8100_i2c->addr;
+ rmsg[1].flags = I2C_M_FCIWR;
+ rmsg[1].len = 1;
+ rmsg[1].buf = i2c_data;
+ i2c_data[0] = addr & 0xff;
+
+ rmsg[2].addr = fc8100_i2c->addr;
+ rmsg[2].flags = I2C_M_FCIRD;
+ rmsg[2].len = length;
+ rmsg[2].buf = data;
+
+ res = i2c_transfer(fc8100_i2c->adapter, &rmsg[0], 3);
+ /* printk("i2c_rf_read data : %x\n", data[0]); */
+
+ /* return status */
+ if (res >= 0)
+ res = 0;
+
+ return res;
+}
+
+static int i2c_rf_write(HANDLE hDevice, u8 addr, u8 *data, u8 length)
+{
+ int res;
+ struct i2c_msg wmsg[2];
+ unsigned char i2c_rp_data[2];
+ unsigned char i2c_data[I2C_MAX_SEND_LENGTH];
+
+ /* printk("i2c_rf_write ENTER addr : %x, data : %x, length : %d\n", addr, data[0], length); */
+ if (length+1 > I2C_MAX_SEND_LENGTH) {
+ printk(".......error");
+ return -ENODEV;
+ }
+
+ wmsg[0].addr = fc8100_i2c->addr;
+ wmsg[0].flags = I2C_M_FCIWR;
+ wmsg[0].len = 2;
+ wmsg[0].buf = i2c_rp_data;
+ i2c_rp_data[0] = 0x02;
+ i2c_rp_data[1] = 0x01;
+
+ wmsg[1].addr = fc8100_i2c->addr;
+ wmsg[1].flags = I2C_M_FCIWR;
+ wmsg[1].len = length+1;
+ wmsg[1].buf = i2c_data;
+ i2c_data[0] = addr & 0xff;
+ memcpy(&i2c_data[1], data, length);
+
+ res = i2c_transfer(fc8100_i2c->adapter, &wmsg[0], 2);
+
+ /* return status */
+ if (res >= 0)
+ res = 0;
+
+ return res;
+}
+
+int fc8100_i2c_init(HANDLE hDevice, u16 param1, u16 param2)
+{
+ int res;
+
+ res = i2c_init();
+
+ return res;
+}
+
+int fc8100_i2c_byteread(HANDLE hDevice, u16 addr, u8 *data)
+{
+ int res = BBM_NOK;
+
+ /* PRINTF(0, "fc8100_i2c_byteread 0x%x\n", addr); */
+ res = i2c_bb_read(hDevice, addr, (u8 *)data, 1);
+
+ return res;
+}
+
+int fc8100_i2c_wordread(HANDLE hDevice, u16 addr, u16 *data)
+{
+ int res = BBM_NOK;
+
+ /* PRINTF(0, "fc8100_i2c_wordread 0x%x\n", addr); */
+ res = i2c_bb_read(hDevice, addr, (u8 *)data, 2);
+
+ return res;
+}
+
+int fc8100_i2c_longread(HANDLE hDevice, u16 addr, u32 *data)
+{
+ int res = BBM_NOK;
+
+ /* PRINTF(0, "fc8100_i2c_longread 0x%x\n", addr); */
+ res = i2c_bb_read(hDevice, addr, (u8 *)data, 4);
+
+ return res;
+}
+
+int fc8100_i2c_bulkread(HANDLE hDevice, u16 addr, u8 *data, u16 size)
+{
+ int res = BBM_NOK;
+
+ /* PRINTF(0, "fc8100_i2c_bulkread 0x%x\n", addr); */
+ res = i2c_bb_read(hDevice, addr, (u8 *)data, size);
+
+ return res;
+}
+
+int fc8100_i2c_bytewrite(HANDLE hDevice, u16 addr, u8 data)
+{
+ int res = BBM_NOK;
+
+ res = i2c_bb_write(hDevice, addr, (u8 *)&data, 1);
+
+ return res;
+}
+
+int fc8100_i2c_wordwrite(HANDLE hDevice, u16 addr, u16 data)
+{
+ int res = BBM_NOK;
+
+ res = i2c_bb_write(hDevice, addr, (u8 *)&data, 2);
+
+ return res;
+}
+
+int fc8100_i2c_longwrite(HANDLE hDevice, u16 addr, u32 data)
+{
+ int res = BBM_NOK;
+
+ res = i2c_bb_write(hDevice, addr, (u8 *)&data, 4);
+
+ return res;
+}
+
+int fc8100_i2c_bulkwrite(HANDLE hDevice, u16 addr, u8 *data, u16 size)
+{
+ int res = BBM_NOK;
+
+ res = i2c_bb_write(hDevice, addr, (u8 *)&data, size);
+
+ return res;
+}
+
+int fc8100_i2c_dataread(HANDLE hDevice, u16 addr, u8 *data, u16 size)
+{
+ int res = BBM_NOK;
+
+ return res;
+}
+
+int fc8100_rf_bulkread(HANDLE hDevice, u8 addr, u8 *data, u8 size)
+{
+ int res = BBM_NOK;
+
+ res = i2c_rf_read(hDevice, addr, (u8 *)data, size);
+
+ return res;
+}
+
+int fc8100_rf_bulkwrite(HANDLE hDevice, u8 addr, u8 *data, u8 size)
+{
+ int res = BBM_NOK;
+
+ res = i2c_rf_write(hDevice, addr, (u8 *)data, size);
+
+ return res;
+}
+
+int fc8100_i2c_deinit(HANDLE hDevice)
+{
+ int res = BBM_NOK;
+
+ res = i2c_deinit();
+
+ return res;
+}
+
+int fc8100_spi_init(HANDLE hDevice, u16 param1, u16 param2)
+{
+
+ return BBM_OK;
+}
+
+int fc8100_spi_dataread(HANDLE hDevice, u16 addr, u8 *pBuf, u16 nLength)
+{
+ return BBM_OK;
+}
diff --git a/drivers/media/isdbt/fc8100/fc8100_i2c.h b/drivers/media/isdbt/fc8100/fc8100_i2c.h
new file mode 100644
index 0000000..3bd2a13
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100_i2c.h
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8100_i2c.h
+
+ Description : API of dmb baseband module
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/10/01 bruce initial
+*******************************************************************************/
+
+#ifndef __FC8100_I2C__
+#define __FC8100_I2C__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int fc8100_i2c_init(HANDLE hDevice, u16 param1, u16 param2);
+
+extern int fc8100_i2c_byteread(HANDLE hDevice, u16 param1, u8 *param2);
+extern int fc8100_i2c_wordread(HANDLE hDevice, u16 param1, u16 *param2);
+extern int fc8100_i2c_longread(HANDLE hDevice, u16 param1, u32 *param2);
+extern int fc8100_i2c_bulkread(HANDLE hDevice, u16 param1, u8 *param2, u16 param3);
+extern int fc8100_i2c_bytewrite(HANDLE hDevice, u16 param1, u8 param2);
+extern int fc8100_i2c_wordwrite(HANDLE hDevice, u16 param1, u16 param2);
+extern int fc8100_i2c_longwrite(HANDLE hDevice, u16 param1, u32 param2);
+extern int fc8100_i2c_bulkwrite(HANDLE hDevice, u16 param1, u8 *param2, u16 param3);
+
+extern int fc8100_i2c_deinit(HANDLE hDevice);
+
+extern int fc8100_rf_bulkread(HANDLE hDevice, u8 addr, u8 *data, u8 len);
+extern int fc8100_rf_bulkwrite(HANDLE hDevice, u8 addr, u8 *data, u8 len);
+
+extern int fc8100_spi_init(HANDLE hDevice, u16 param1, u16 param2);
+extern int fc8100_spi_dataread(HANDLE hDevice, u16 addr, u8 *pBuf, u16 nLength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/fc8100/fc8100_isr.c b/drivers/media/isdbt/fc8100/fc8100_isr.c
new file mode 100644
index 0000000..5b6d6a3
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100_isr.c
@@ -0,0 +1,27 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8100_isr.c
+
+ Description : fc8100 interrupt service routine
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/12/11 ckw initial
+*******************************************************************************/
+#include "fci_types.h"
+#include "fci_hal.h"
+
+u32 gUserData;
+int (*pCallback)(u32 userdata, u8 *data, int length) = NULL;
+
+u8 dmbBuffer[188*4];
+
+void fc8100_isr(HANDLE hDevice)
+{
+
+ bbm_data(hDevice, 0, &dmbBuffer[0], 188*2);
+
+ if (pCallback)
+ (*pCallback)(gUserData, &dmbBuffer[0], 188);
+}
diff --git a/drivers/media/isdbt/fc8100/fc8100_isr.h b/drivers/media/isdbt/fc8100/fc8100_isr.h
new file mode 100644
index 0000000..9d6e59b
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100_isr.h
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8100_isr.c
+
+ Description : API of dmb baseband module
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/12/11 ckw initial
+*******************************************************************************/
+
+#ifndef __FC8000_ISR__
+#define __FC8000_ISR__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "fci_types.h"
+
+extern u32 gUserData;
+extern int (*pCallback)(u32 userdata, u8 *data, int length);
+
+extern void fc8100_isr(HANDLE hDevice);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/fc8100/fc8100_regs.h b/drivers/media/isdbt/fc8100/fc8100_regs.h
new file mode 100644
index 0000000..08b7b7e
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100_regs.h
@@ -0,0 +1,337 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8100_regs.h
+
+ Description : RF & baseband registermap header file
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/09/29 bruce initial
+*******************************************************************************/
+
+#ifndef __FC8100_REGS_H__
+#define __FC8100_REGS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*----------------------------------------------------
+ FC8100 COMMON DEFINTION
+----------------------------------------------------*/
+#define BER_PACKET_SIZE 1 /* // 256 PACKET PERIOD */
+
+
+/*----------------------------------------------------
+ FC8100 RF REGISTER MAP
+----------------------------------------------------*/
+
+/* // -- CONTROL -- */
+#define RF_MODULE_RESET 0x00
+#define RF_TUNER_CHIP_ID 0x01
+#define RF_MODE_CTL 0x02
+#define RF_MANUAL_CTL 0x03
+#define RF_STBY_ACTIVE1 0x04
+#define RF_STBY_ACTIVE2 0x05
+#define RF_STBY_ACTIVE3 0x06
+#define RF_STBY_ACTIVE4 0x07
+
+/* // -- VCO -- */
+#define RF_VCO_MODE 0x08
+#define RF_LO_BIAS_MODE1 0x09
+#define RF_LO_BIAS_MODE2 0x0A
+
+/* // -- PLL, LNA&Mixer, CSF, Output Buffer, Bias Top -- */
+#define RF_BIAS_TOP_CTRL 0x0B
+
+/* //-- PGA, ADC, AGC, Revision Number, LNA, Common Bias, VGA -- */
+#define RF_LNA_ELNA_Control 0x0C
+#define RF_PLL_MODE1 0x0D
+#define RF_PLL_CTRL1 0x0E
+#define RF_ELNA_CONTROL_OFF 0x0F
+#define RF_PLL_CTRL3 0x10
+#define RF_ELNA_CONTROL_ON 0x11
+#define RF_PLL_CTRL4 0x12
+#define RF_PLL_CTRL5 0x13
+#define RF_PLL_CTRL6 0x14
+#define RF_PLL_CTRL7 0x15
+#define RF_PLL_K2 0x16
+#define RF_NTARGET_VALUE 0x17
+#define RF_PLL_K1 0x18
+#define RF_PLL_K0 0x19
+#define RF_PLL_N 0x1A
+#define RF_ELNA_CONTROL1 0x1B
+#define RF_ELNA_CONTROL2 0x1C
+#define RF_PLL_CTRL10 0x1D
+#define RF_PLL_CTRL11 0x1E
+#define RF_DMB_BANK_MONITOR 0x1F
+#define RF_LOCK_CTRL0 0x20
+#define RF_LOCK_CTRL1 0x21
+#define RF_BS_CTRL1 0x22
+#define RF_BS_CTRL2 0x23
+#define RF_BS_CTRL3 0x24
+#define RF_BS_CTRL4 0x25
+#define RF_BS_MON1 0x26
+#define RF_BS_MON2 0x27
+#define RF_LNAMIX_CTL 0x28
+#define RF_LNA_ICTRL 0x29
+#define RF_LNAMIX_ICTRL1 0x2A
+#define RF_AGC_ELNA 0x2B
+#define RF_LNAMIX_ICTRL2 0x2C
+#define RF_LNAMIX_ICTRL3 0x2D
+#define RF_LNAMIX_ICTRL4 0x2E
+#define RF_LNAMIX_ICTRL5 0x2F
+#define RF_LNAMIX_ICTRL_MON 0x30
+#define RF_ELNA_GAIN 0x31
+#define RF_CSF_MODE 0x32
+#define RF_CSF_CAPTUNE_MON1 0x33
+#define RF_CSF_CAPTUNE_MON2 0x34
+#define RF_CSFA_I2C_CRNT 0x35
+#define RF_CSF_I2C_CORE_CRNT_AH 0x36
+#define RF_CSF_I2C_OUT_CRNT_AH 0x37
+#define RF_CSF_RX_CRNT 0x38
+#define RF_CSF_PRE_CUR 0x39
+#define RF_CSF_STATE 0x3A
+#define RF_ELNA_CONTROL3 0x3B
+#define RF_CSF_CAL_CRNT 0x3C
+#define RF_CSF_CF_CLK_DIV_LSB 0x3D
+#define RF_CSF_CLK_DIV_LSB 0x3E
+#define RF_CSF_AUTO_RECAL_PERIOD 0x3F
+#define RF_CSF_CAL_MAN1 0x40
+#define RF_CSF_CAL_MAN2 0x41
+#define RF_CSF_AGC_CRNT_LOW 0x42
+#define RF_BG_CTRL0 0x43
+#define RF_PGA_1ST_STATE_CUR 0x44
+#define RF_PGA_2ND_STATE_CUR 0x45
+#define RF_ELNA_CONTROL4 0x46
+#define RF_PGA_MODE 0x47
+#define RF_AGC_COMP_BIAS 0x48
+#define RF_W_FACTOR1 0x49
+#define RF_ADC_BIAS1 0x4A
+#define RF_ADC1_BOUT 0x4B
+#define RF_W_FACTOR2 0x4C
+#define RF_ADC_BIAS2 0x4D
+#define RF_ADC2_BOUT 0x4E
+#define RF_ADC_BIAS3 0x4F
+#define RF_ADC3_BOUT 0x50
+#define RF_ADC4_BOUT 0x51
+#define RF_RFAGC_MODE 0x52
+#define RF_RFAGC_MODE2 0x53
+#define RF_IFAGC_MODE1 0x54
+#define RF_RFAGC_TEST_MODE1 0x55
+#define RF_RFAGC_TEST_MODE2 0x56
+#define RF_IFAGC_TEST_MODE1 0x57
+#define RF_IFAGC_TEST_MODE2 0x58
+#define RF_PD1_MAX 0x59
+#define RF_PD1_MIN 0x5A
+#define RF_PD2_MAX 0x5B
+#define RF_PD2_MIN 0x5C
+#define RF_AGC_CLK_MODE 0x5D
+#define RF_RFAGC_WAIT_CLK_LNA1 0x5F
+#define RF_RFAGC_WAIT_CLK_LNA2 0x60
+#define RF_RFAGC_WAIT_CLK_RFVGA 0x61
+#define RF_RFAGC_WAIT_CLK_PD_CHANGE 0x62
+#define RF_RFAGC_WAIT_CLK_STDBY 0x63
+#define RF_RFAGC_WAIT_CLK_HOLDAGC 0x64
+#define RF_IFAGC_WAIT_CLK_FILTER 0x65
+#define RF_IFAGC_WAIT_CLK_STBY 0x66
+#define RF_IFAGC_WAIT_CLK_HOLD_OFF 0x67
+#define RF_PGA_AGC_STEP 0x68
+#define RF_RFVGA_L0_MAX 0x69
+#define RF_RFVGA_L0_MIN 0x6A
+#define RF_RFVGA_L1_MAX 0x6B
+#define RF_RFVGA_L1_MIN 0x6C
+#define RF_RFVGA_L2_MAX 0x6D
+#define RF_RFVGA_L2_MIN 0x6E
+#define RF_RFVGA_L3_MAX 0x6F
+#define RF_RFVGA_L3_MIN 0x70
+#define RF_RFVGA_L4_MAX 0x71
+#define RF_RFVGA_L4_MIN 0x72
+#define RF_RFVGA_L5_MAX 0x73
+#define RF_RFVGA_L5_MIN 0x74
+#define RF_RFVGA_L6_MAX 0x75
+#define RF_RFVGA_L6_MIN 0x76
+#define RF_IFAGC_PGA_MAX 0x77
+#define RF_IFAGC_PGA_MIN 0x78
+#define RF_STATE_MONITOR1 0x79
+#define RF_STATE_MONITOR2 0x7A
+#define RF_STATE_MONITOR3 0x7B
+#define RF_STATE_MONITOR4 0x7C
+#define RF_AGC_PD_OFFSET 0x7D
+#define RF_AGC_SH_SL 0x7E
+#define RF_REVISION_NUMBER 0x7F
+
+
+/* ----------------------------------------------------
+ FC8100 BB REGISTER MAP
+----------------------------------------------------*/
+
+/* // 1. System Control */
+#define BBM_VERSION 0x00
+#define BBM_SYSRST 0x01
+
+/* // 2. Serial Bus Control */
+#define BBM_SBCTRL 0x02
+#define BBM_SBADDR 0x03
+#define BBM_INCTRL 0x05
+#define BBM_IOMODE 0x07
+#define BBM_OUTCTRL0 0x08
+#define BBM_OUTCTRL1 0x09
+#define BBM_PLL0 0x0C
+#define BBM_PLL1 0x0D
+#define BBM_PLL2 0x0E
+
+/* // 3. INTR */
+#define BBM_INTRPT0 0x11
+#define BBM_INTRPT1 0x12
+#define BBM_INTSEL0 0x14
+#define BBM_INTSEL1 0x15
+#define BBM_INTRST0 0x17
+#define BBM_INTRST1 0x18
+#define BBM_RSINTR 0x19
+#define BBM_INTFORM 0x1C
+
+/* // 4. LOCK */
+#define BBM_LOCKF 0x1D
+#define BBM_GIVEUP 0x1E
+
+/* // 5. TMCC */
+#define BBM_TMCRNT0 0x20
+#define BBM_TMCRNT1 0x21
+#define BBM_TMCRNT2 0x22
+#define BBM_TMNEXT0 0x26
+#define BBM_TMNEXT1 0x27
+#define BBM_TMMAND0 0x2B
+#define BBM_TMMAND1 0x2C
+#define BBM_TMMNSW 0x30
+#define BBM_TMFECF 0x31
+
+/* // 7. MONITOR */
+#define BBM_STATEF 0x32
+#define BBM_DCDF 0x33
+#define BBM_INPWR0 0x34
+#define BBM_INPWR1 0x35
+#define BBM_AGADAT 0x36
+#define BBM_EQIDAT0 0x38
+#define BBM_EQIDAT1 0x39
+#define BBM_EQQDAT0 0x3A
+#define BBM_EQQDAT1 0x3B
+
+/* // 8. AGC Setup */
+#define BBM_AGTIME 0x40
+#define BBM_AGAVCNT 0x41
+#define BBM_AGTG 0x42
+#define BBM_AGSG 0x43
+#define BBM_AGAINI 0x44
+#define BBM_AGREF0 0x46
+#define BBM_AGREF1 0x47
+#define BBM_AGCTRL 0x4D
+
+/* // 9. GPIO */
+#define BBM_GPIOSEL0 0x59
+#define BBM_GPIOSEL1 0x5A
+#define BBM_GPI 0x5B
+#define BBM_GPO 0x5C
+#define BBM_PWMSET 0x5D
+#define BBM_PWMLV0 0x5E
+#define BBM_PWMLV1 0x5F
+
+/* // 10. Read-Solomon decoder/error counter */
+#define BBM_RSERST 0x60
+#define BBM_RSECNT0 0x61
+#define BBM_RSECNT1 0x62
+#define BBM_RSECNT2 0x63
+#define BBM_RSTCNT0 0x64
+#define BBM_RSTCNT1 0x65
+#define BBM_RSEPER 0x70
+
+/* // 11. Block through */
+#define BBM_THRUFD 0x73
+#define BBM_THRUBD 0x74
+#define BBM_PREVTO 0x76
+#define BBM_THRURS 0x77
+#define BBM_THRUDR 0x78
+
+/* // 12. Symbo synchronization */
+#define BBM_SYTIME 0xA0
+#define BBM_SYATTH 0xA1
+#define BBM_SYMNTH0 0xA2
+#define BBM_SYMNTH1 0xA3
+#define BBM_SYSW1 0xA4
+#define BBM_SYSW2 0xA5
+#define BBM_SYCTRL1 0xA6
+#define BBM_SYMODE1 0xA7
+#define BBM_SYMODE2 0xA8
+#define BBM_SYMODE3 0xA9
+
+/* // 13. Digital AGC */
+#define BBM_DAM2REF0 0xAA
+#define BBM_DAM2REF1 0xAB
+#define BBM_DAM3REF0 0xAC
+#define BBM_DAM3REF1 0xAD
+#define BBM_DAAVCNT 0xAE
+#define BBM_DALPG 0xAF
+
+/* // 14. FFT */
+#define BBM_FTCTRL 0xB0
+
+/* // 15. TMCC Decoder */
+#define BBM_TMCTRL0 0xBC
+#define BBM_TMCTRL1 0xBD
+#define BBM_TMCTRL2 0xBE
+#define BBM_EQCTRL 0xC0
+#define BBM_EQCONF 0xC1
+#define BBM_PRBSEL 0xC3
+#define BBM_GNFCNT1 0xC4
+
+/* // 17. IFFT */
+#define BBM_GNFSNTH 0xC5
+#define BBM_GNFCNT2 0xC7
+#define BBM_WINPTMN 0xC8
+#define BBM_IFCTRL 0xC9
+#define BBM_WINCTRL 0xCA
+#define BBM_WINCTRL1 0xCB
+#define BBM_WINCTRL2_1 0xCC
+#define BBM_WINCTRL2_2 0xCD
+#define BBM_WINCTRL2_3 0xCE
+
+/* // 18. TIME RANGE UNLOCK DETECTION */
+#define BBM_IFUN 0xCF
+
+/* // 19. Status readout */
+#define BBM_FRLKCNT0 0xD0
+#define BBM_FRLKCNT1 0xD1
+#define BBM_SYLKCNT0 0xD2
+#define BBM_SYLKCNT1 0xD3
+#define BBM_MRLKCNT0 0xD4
+#define BBM_MRLKCNT1 0xD5
+#define BBM_ULSTAT 0xD6
+#define BBM_SELGNF 0xD7
+#define BBM_ERRPWR1 0xD8
+#define BBM_ERRPWR2 0xD9
+
+/* // 20. GIC */
+#define BBM_GICCNT1 0xE7
+#define BBM_GICCNT2 0xE8
+#define BBM_WINTHTR 0xE9
+#define BBM_GICOFF 0xEA
+
+/* // 21. Antenna switching */
+#define BBM_AWCTRL 0xF0
+#define BBM_AWSWTH 0xF1
+#define BBM_AWONTH 0xF2
+#define BBM_AWOFFTH 0xF3
+#define BBM_AWAGCTH 0xF4
+#define BBM_AWAVCE 0xF5
+
+/* // 22. SI */
+#define BBM_EQSI1 0xF6
+#define BBM_EQSI2 0xF7
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/fc8100/fc8100_tun.c b/drivers/media/isdbt/fc8100/fc8100_tun.c
new file mode 100644
index 0000000..e9fa291
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100_tun.c
@@ -0,0 +1,351 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8100_tun.c
+
+ Description : fc8100 tuner controller
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/09/29 bruce initial
+*******************************************************************************/
+#include "fci_types.h"
+#include "fci_oal.h"
+#include "fci_tun.h"
+#include "fc8100_regs.h"
+#include "fci_hal.h"
+
+#define TUN_IF_FREQ 500 /* 500 or 1000 (Khz) */
+/*
+select BB Xtal frequency
+16Mhz: 16000 18Mhz:18000 19.2Mhz:19200 24Mhz:24000
+26Mhz:26000 32Mhz:32000 40Mhz:40000
+*/
+#define FC8100_FREQ_XTAL_TUNER 26000 /* 26MHz */
+#define DEFAULT_CH_FREQ 617143 /* 37 ch, freq : 617.143Mhz */
+#define CP_BOOT_CURRENT 0 /* 0:250uA 1: 500uA */
+
+static int fc8100_write(HANDLE hDevice, u8 addr, u8 data)
+{
+ int res = BBM_NOK;
+
+ res = tuner_i2c_write(hDevice, addr, 1, &data, 1);
+
+ return res;
+}
+
+static int fc8100_read(HANDLE hDevice, u8 addr, u8 *data)
+{
+ int res = BBM_NOK;
+ res = tuner_i2c_read(hDevice, addr, 1, data, 1);
+ return res;
+}
+
+static int fc8100_tuner_set_init(HANDLE hDevice)
+{
+ int res = BBM_NOK;
+
+ res = fc8100_write(hDevice, RF_MODULE_RESET, 0x00);
+
+ /* PLL & VCO Setting */
+ /* if ghost channel scan occurred, change charge pump currnet 500uA -> 250uA */
+ if (CP_BOOT_CURRENT == 1) {
+ /* 500uA */
+ res |= fc8100_write(hDevice, RF_PLL_CTRL4, 0x91);
+ } else {
+ /* 250 uA */
+ res |= fc8100_write(hDevice, RF_PLL_CTRL4, 0x11);
+ }
+
+ res |= fc8100_write(hDevice, RF_PLL_CTRL11, 0x00);
+ res |= fc8100_write(hDevice, RF_PLL_MODE1, 0x40);
+ res |= fc8100_write(hDevice, RF_LO_BIAS_MODE1, 0x27);
+ res |= fc8100_write(hDevice, RF_BIAS_TOP_CTRL, 0x19);
+ res |= fc8100_write(hDevice, RF_PLL_CTRL6, 0x13);
+ /* LNA & MIX Setting */
+ res |= fc8100_write(hDevice, RF_LNA_ICTRL, 0x30);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL1, 0x33);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL2, 0xAF);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL3, 0x06);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL5, 0x00);
+ /* AGC_ADC Setting */
+ res |= fc8100_write(hDevice, RF_ADC_BIAS1, 0xB2);
+ res |= fc8100_write(hDevice, RF_W_FACTOR1, 0x40);
+ res |= fc8100_write(hDevice, RF_ADC_BIAS2, 0x32);
+ res |= fc8100_write(hDevice, RF_W_FACTOR2, 0x40);
+ res |= fc8100_write(hDevice, RF_PD1_MAX, 0x36);
+ res |= fc8100_write(hDevice, RF_PD1_MIN, 0x2D);
+ res |= fc8100_write(hDevice, RF_PD2_MAX, 0x1F);
+ res |= fc8100_write(hDevice, RF_PD2_MIN, 0x1B);
+ res |= fc8100_write(hDevice, RF_AGC_CLK_MODE, 0x73);
+ res |= fc8100_write(hDevice, RF_AGC_PD_OFFSET, 0x88);
+ res |= fc8100_write(hDevice, RF_RFAGC_WAIT_CLK_RFVGA, 0x28);
+ res |= fc8100_write(hDevice, RF_RFAGC_WAIT_CLK_PD_CHANGE, 0x1F);
+ res |= fc8100_write(hDevice, RF_IFAGC_WAIT_CLK_FILTER, 0x14);
+ res |= fc8100_write(hDevice, RF_RFVGA_L0_MAX, 0x0C);
+ res |= fc8100_write(hDevice, RF_RFVGA_L1_MAX, 0x0C);
+ res |= fc8100_write(hDevice, RF_RFVGA_L2_MAX, 0x0C);
+ res |= fc8100_write(hDevice, RF_RFVGA_L3_MAX, 0x0C);
+ res |= fc8100_write(hDevice, RF_RFVGA_L4_MAX, 0x0C);
+ res |= fc8100_write(hDevice, RF_RFVGA_L5_MAX, 0x0C);
+ res |= fc8100_write(hDevice, RF_RFVGA_L6_MAX, 0x20);
+ res |= fc8100_write(hDevice, RF_IFAGC_PGA_MAX, 0x78);
+ res |= fc8100_write(hDevice, RF_IFAGC_PGA_MIN, 0x3c);
+ res |= fc8100_write(hDevice, RF_LNA_ELNA_Control, 0x11);
+
+ return res;
+}
+
+static int fc8100_tuner_set_filter(HANDLE hDevice, unsigned int xtal)
+{
+ int res = BBM_NOK;
+ u8 reg_3D, reg_3E;
+ float value;
+
+ value = (float)xtal / 1000;
+ reg_3D = (unsigned char)(value * 5.375f);
+ reg_3E = (unsigned char)(value * 4.3125f);
+
+ /* Filter Setting for defined x-tal */
+ res = fc8100_write(hDevice, RF_IFAGC_TEST_MODE2, 0x50);
+ res |= fc8100_write(hDevice, RF_CSFA_I2C_CRNT, 0x3F);
+ res |= fc8100_write(hDevice, RF_CSF_I2C_CORE_CRNT_AH, 0xFF);
+ res |= fc8100_write(hDevice, RF_CSF_I2C_OUT_CRNT_AH, 0xFF);
+ res |= fc8100_write(hDevice, RF_CSF_RX_CRNT, 0xEA);
+ res |= fc8100_write(hDevice, RF_CSF_PRE_CUR, 0x54);
+ res |= fc8100_write(hDevice, RF_CSF_CAL_CRNT, 0x40);
+ res |= fc8100_write(hDevice, RF_CSF_CF_CLK_DIV_LSB, reg_3D);
+ res |= fc8100_write(hDevice, RF_CSF_CLK_DIV_LSB, reg_3E);
+ res |= fc8100_write(hDevice, RF_CSF_AGC_CRNT_LOW, 0x00);
+ res |= fc8100_write(hDevice, RF_CSF_MODE, 0x09);
+ res |= fc8100_write(hDevice, RF_CSF_MODE, 0x01);
+
+ return res;
+}
+
+
+/*=======================================================
+ FUNCTION fc8100_tuner_set_etc
+
+ DESCRIPTION
+ Set Default Channel
+
+ PARAMETERS
+ unsigned ing xtal : xtal value, ex)if 32MHz, xtal = 32000
+
+ DEPENDENCIES
+ None
+
+ RETURN VALUE
+ 0 if successful
+ others if fail
+
+ SIDE EFFECTS
+ None.
+ =========================================================*/
+static int fc8100_tuner_set_etc(HANDLE hDevice, unsigned int xtal)
+{
+ int res = BBM_NOK;
+ unsigned int f_rf = DEFAULT_CH_FREQ;
+ unsigned int f_if = TUN_IF_FREQ;
+ unsigned int f_diff, f_diff_shifted, n_val, k_val;
+ unsigned int r_val;
+ unsigned int f_comp;
+ unsigned int f_lo = f_rf - f_if;
+ unsigned int f_vco = f_lo * 4;
+ unsigned char pre_shift_bits, data_0x16;
+ unsigned char i;
+ unsigned char filtercal;
+
+ r_val = (f_vco >= 25 * xtal) ? 1 : 2;
+ f_comp = xtal/r_val;
+
+ pre_shift_bits = 4;
+
+ n_val = f_vco / f_comp;
+
+ f_diff = f_vco - f_comp * n_val;
+ f_diff_shifted = f_diff << (20 - pre_shift_bits);
+ k_val = (f_diff_shifted + (f_comp >> (pre_shift_bits+1)))/(f_comp >> pre_shift_bits);
+
+ data_0x16 = ((r_val == 1) ? 0x00 : 0x10) + (unsigned char)(k_val >> 16);
+
+ /* ISDBT_ON_AGC_AUTO_0p1 - for defined x-tal */
+ res = fc8100_write(hDevice, RF_MODE_CTL, 0x06);
+ res |= fc8100_write(hDevice, RF_ADC_BIAS3, 0x80);
+ res |= fc8100_write(hDevice, RF_RFAGC_MODE, 0xC1);
+ res |= fc8100_write(hDevice, RF_RFAGC_MODE2, 0x20);
+ /* Default Channel Setting */
+ res |= fc8100_write(hDevice, RF_PLL_K2, data_0x16);
+ res |= fc8100_write(hDevice, RF_PLL_K1, (unsigned char)(k_val >> 8));
+ res |= fc8100_write(hDevice, RF_PLL_K0, (unsigned char)(k_val));
+ res |= fc8100_write(hDevice, RF_PLL_N, (unsigned char)(n_val));
+ /* Filter Cal */
+ res |= fc8100_write(hDevice, RF_CSF_MODE, 0x09);
+
+ msWait(10);
+ for (i = 0; i < 10; i++) {
+ fc8100_read(hDevice, RF_CSF_CAPTUNE_MON1, &filtercal);
+ if ((filtercal & 0xC0) != 0xC0) {
+ fc8100_write(hDevice, RF_CSF_MODE, 0x09);
+ msWait(10);
+ fc8100_write(hDevice, RF_CSF_MODE, 0x01);
+ }
+ }
+ res |= fc8100_write(hDevice, RF_CSF_MODE, 0x01);
+
+ return res;
+}
+
+/*=======================================================
+ FUNCTION fc8100_tuner_init
+
+ DESCRIPTION
+ FC8100 RF Tuner Register Init
+
+ PARAMETERS
+ None
+
+ DEPENDENCIES
+ None
+
+ RETURN VALUE
+ 0 if successful.
+ others if fail.
+
+ SIDE EFFECTS
+ None.
+ =========================================================*/
+int fc8100_tuner_init(HANDLE hDevice, u8 band_type)
+{
+ int res = BBM_NOK;
+
+ res = fc8100_tuner_set_init(hDevice);
+ res |= fc8100_tuner_set_filter(hDevice, FC8100_FREQ_XTAL_TUNER);
+ res |= fc8100_tuner_set_etc(hDevice, FC8100_FREQ_XTAL_TUNER);
+
+ return res;
+}
+
+int fc8100_tuner_deinit(HANDLE hDevice)
+{
+ int res = BBM_NOK;
+
+ return res;
+}
+
+int fc8100_set_freq(HANDLE hDevice, u8 ch_num)
+{
+ int res = BBM_NOK;
+
+ unsigned int f_diff, f_diff_shifted, n_val, k_val;
+ unsigned int r_val;
+ unsigned int f_comp;
+ unsigned int f_lo;
+ unsigned int f_vco;
+ u8 pre_shift_bits, data_0x16;
+ unsigned int xtal = FC8100_FREQ_XTAL_TUNER;
+
+ unsigned int f_rf;
+ unsigned int f_if;
+
+ PRINTF(0, "Channel Nummber : %d\n", ch_num);
+
+ f_rf = (ch_num - 13) * 6000 + 473143;
+ f_if = TUN_IF_FREQ;
+
+ f_lo = f_rf - f_if;
+ f_vco = f_lo * 4;
+
+ r_val = (f_vco >= 25*xtal) ? 1 : 2;
+ f_comp = xtal/r_val;
+
+ pre_shift_bits = 4;
+
+ n_val = f_vco / f_comp;
+
+ f_diff = f_vco - f_comp * n_val;
+ f_diff_shifted = f_diff << (20 - pre_shift_bits);
+ k_val = (f_diff_shifted + (f_comp >> (pre_shift_bits+1))) / (f_comp >> pre_shift_bits);
+
+ if (f_vco < 2180000) {
+ res = fc8100_write(hDevice, RF_LO_BIAS_MODE1, 0xE7);
+ res |= fc8100_write(hDevice, RF_BIAS_TOP_CTRL, 0x99);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL2, 0xBF);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL3, 0x1F);
+ } else if (f_vco < 2276000) {
+ res = fc8100_write(hDevice, RF_LO_BIAS_MODE1, 0xE7);
+ res |= fc8100_write(hDevice, RF_BIAS_TOP_CTRL, 0x99);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL2, 0xAF);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL3, 0x1F);
+ } else if (f_vco < 2420000) {
+ res = fc8100_write(hDevice, RF_LO_BIAS_MODE1, 0xE7);
+ res |= fc8100_write(hDevice, RF_BIAS_TOP_CTRL, 0x99);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL2, 0xAF);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL3, 0x0F);
+ } else if (f_vco < 2516000) {
+ res = fc8100_write(hDevice, RF_LO_BIAS_MODE1, 0x27);
+ res |= fc8100_write(hDevice, RF_BIAS_TOP_CTRL, 0x19);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL2, 0xAF);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL3, 0x06);
+ } else if (f_vco < 2588000) {
+ res = fc8100_write(hDevice, RF_LO_BIAS_MODE1, 0x27);
+ res |= fc8100_write(hDevice, RF_BIAS_TOP_CTRL, 0x19);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL2, 0xA6);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL3, 0x06);
+ } else if (f_vco < 2636000) {
+ res = fc8100_write(hDevice, RF_LO_BIAS_MODE1, 0x27);
+ res |= fc8100_write(hDevice, RF_BIAS_TOP_CTRL, 0x19);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL2, 0xA6);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL3, 0x00);
+ } else {
+ res = fc8100_write(hDevice, RF_LO_BIAS_MODE1, 0x27);
+ res |= fc8100_write(hDevice, RF_BIAS_TOP_CTRL, 0x19);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL2, 0xA0);
+ res |= fc8100_write(hDevice, RF_LNAMIX_ICTRL3, 0x00);
+ }
+
+ if (res == BBM_NOK)
+ return res;
+
+ data_0x16 = ((r_val == 1) ? 0x00 : 0x10) + (unsigned char)(k_val >> 16);
+ res = fc8100_write(hDevice, RF_PLL_K2, data_0x16);
+ res |= fc8100_write(hDevice, RF_PLL_K1, (unsigned char)(k_val >> 8));
+ res |= fc8100_write(hDevice, RF_PLL_K0, (unsigned char)(k_val));
+ res |= fc8100_write(hDevice, RF_PLL_N, (unsigned char)(n_val));
+
+ if (res)
+ return res;
+
+ msWait(3);
+ /* SQSTBY is need */
+ bbm_write(hDevice, BBM_SYSRST, 0x02);
+
+ return res;
+}
+
+int fc8100_get_rssi(HANDLE hDevice, s32 *rssi)
+{
+ int res = BBM_NOK;
+ u8 LNA, RFVGA, GSF, PGA;
+ /* float RSSI = 0.0f; */
+ s32 K = -73;
+
+ res = fc8100_read(hDevice, 0x79, &LNA);
+ res |= fc8100_read(hDevice, 0x7A, &RFVGA);
+ res |= fc8100_read(hDevice, 0x7B, &GSF);
+ res |= fc8100_read(hDevice, 0x7C, &PGA);
+
+ if (res) {
+ *rssi = (s32)0xFFFFFFFF;
+ return res;
+ }
+
+ /* RSSI = (LNA * 6) + (RFVGA) + ((GSF & 0x7) * 6) - (PGA * 0.25f) + K; */
+
+ /* *rssi = (RSSI); */
+
+ *rssi = (LNA * 6) + (RFVGA) + ((GSF & 0x7) * 6) - (PGA >> 2) + K;
+
+ return res;
+}
diff --git a/drivers/media/isdbt/fc8100/fc8100_tun.h b/drivers/media/isdbt/fc8100/fc8100_tun.h
new file mode 100644
index 0000000..984527c
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fc8100_tun.h
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8100_tun.h
+
+ Description : fc8100 tuner controller header file
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/09/29 bruce initial
+*******************************************************************************/
+
+#ifndef __FC8100_TUNER__
+#define __FC8100_TUNER__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int fc8100_tuner_init(HANDLE hDevice, u8 band_type);
+extern int fc8100_tuner_deinit(HANDLE hDevice);
+extern int fc8100_set_freq(HANDLE hDevice, u8 ch_num);
+extern int fc8100_get_rssi(HANDLE hDevice, s32 *i32RSSI);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/fc8100/fci_hal.c b/drivers/media/isdbt/fc8100/fci_hal.c
new file mode 100644
index 0000000..952f44e
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fci_hal.c
@@ -0,0 +1,199 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8100_hal.c
+
+ Description : fc8100 host interface
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/08/29 jason initial
+*******************************************************************************/
+
+#include "fci_types.h"
+#include "fci_oal.h"
+#include "bbm.h"
+#include "fci_hal.h"
+#include "fc8100_i2c.h"
+
+typedef struct {
+ int (*init)(HANDLE hDevice, u16 param1, u16 param2);
+
+ int (*byteread)(HANDLE hDevice, u16 addr, u8 *data);
+ int (*wordread)(HANDLE hDevice, u16 addr, u16 *data);
+ int (*longread)(HANDLE hDevice, u16 addr, u32 *data);
+ int (*bulkread)(HANDLE hDevice, u16 addr, u8 *data, u16 size);
+
+ int (*bytewrite)(HANDLE hDevice, u16 addr, u8 data);
+ int (*wordwrite)(HANDLE hDevice, u16 addr, u16 data);
+ int (*longwrite)(HANDLE hDevice, u16 addr, u32 data);
+ int (*bulkwrite)(HANDLE hDevice, u16 addr, u8 *data, u16 size);
+ int (*dataread)(HANDLE hDevice, u16 addr, u8 *data, u16 size);
+
+ int (*deinit)(HANDLE hDevice);
+} IF_PORT;
+
+static IF_PORT i2cif = {
+ &fc8100_i2c_init,
+
+ &fc8100_i2c_byteread,
+ &fc8100_i2c_wordread,
+ &fc8100_i2c_longread,
+ &fc8100_i2c_bulkread,
+
+ &fc8100_i2c_bytewrite,
+ &fc8100_i2c_wordwrite,
+ &fc8100_i2c_longwrite,
+ &fc8100_i2c_bulkwrite,
+ &fc8100_spi_dataread,
+
+ &fc8100_i2c_deinit
+};
+
+static IF_PORT *ifport = &i2cif;
+static u8 hostif_type = BBM_I2C;
+
+int bbm_hostif_get(HANDLE hDevice, u8 *hostif)
+{
+ *hostif = hostif_type;
+
+ return BBM_OK;
+}
+
+int bbm_hostif_select(HANDLE hDevice, u8 hostif)
+{
+ int res = BBM_OK;
+
+ hostif_type = hostif;
+
+ switch (hostif) {
+#if 0
+ case BBM_HPI:
+ ifport = &hpiif;
+ break;
+ case BBM_SPI:
+ ifport = &spiif;
+ break;
+#endif
+ case BBM_I2C:
+ ifport = &i2cif;
+ break;
+ default:
+ res = BBM_NOK;
+ break;
+ }
+
+ if (res == BBM_OK)
+ ifport->init(hDevice, 0, 0);
+
+ return res;
+}
+
+int bbm_hostif_deselect(HANDLE hDevice)
+{
+ int res = BBM_OK;
+
+ ifport->deinit(hDevice);
+
+ hostif_type = 0;
+ ifport = NULL;
+
+ return res;
+}
+
+int bbm_read(HANDLE hDevice, u16 addr, u8 *data)
+{
+ int res;
+
+ res = ifport->byteread(hDevice, addr, data);
+
+ return res;
+}
+
+int bbm_byte_read(HANDLE hDevice, u16 addr, u8 *data)
+{
+ int res;
+
+ res = ifport->byteread(hDevice, addr, data);
+
+ return res;
+}
+
+int bbm_word_read(HANDLE hDevice, u16 addr, u16 *data)
+{
+ int res;
+
+ res = ifport->wordread(hDevice, addr, data);
+
+ return res;
+}
+
+int bbm_long_read(HANDLE hDevice, u16 addr, u32 *data)
+{
+ int res;
+
+ res = ifport->longread(hDevice, addr, data);
+
+ return res;
+}
+
+int bbm_bulk_read(HANDLE hDevice, u16 addr, u8 *data, u16 length)
+{
+ int res;
+
+ res = ifport->bulkread(hDevice, addr, data, length);
+
+ return res;
+}
+
+int bbm_write(HANDLE hDevice, u16 addr, u8 data)
+{
+ int res;
+
+ res = ifport->bytewrite(hDevice, addr, data);
+
+ return res;
+}
+
+int bbm_byte_write(HANDLE hDevice, u16 addr, u8 data)
+{
+ int res;
+
+ res = ifport->bytewrite(hDevice, addr, data);
+
+ return res;
+}
+
+int bbm_word_write(HANDLE hDevice, u16 addr, u16 data)
+{
+ int res;
+
+ res = ifport->wordwrite(hDevice, addr, data);
+
+ return res;
+}
+
+int bbm_long_write(HANDLE hDevice, u16 addr, u32 data)
+{
+ int res;
+
+ res = ifport->longwrite(hDevice, addr, data);
+
+ return res;
+}
+
+int bbm_bulk_write(HANDLE hDevice, u16 addr, u8 *data, u16 length)
+{
+ int res;
+
+ res = ifport->bulkwrite(hDevice, addr, data, length);
+
+ return res;
+}
+
+int bbm_data(HANDLE hDevice, u16 addr, u8 *data, u16 length)
+{
+ int res = BBM_NOK;
+ res = ifport->dataread(hDevice, addr, data, length);
+ return res;
+}
diff --git a/drivers/media/isdbt/fc8100/fci_hal.h b/drivers/media/isdbt/fc8100/fci_hal.h
new file mode 100644
index 0000000..72634cd
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fci_hal.h
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fc8000_hal.h
+
+ Description : fc8000 host interface header
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/08/29 jason initial
+*******************************************************************************/
+
+#ifndef __FCI_HAL_H__
+#define __FCI_HAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int bbm_hostif_select(HANDLE hDevice, u8 hostif);
+extern int bbm_hostif_deselect(HANDLE hDevice);
+extern int bbm_hostif_get(HANDLE hDevice, u8 *hostif);
+
+extern int bbm_read(HANDLE hDevice, u16 addr, u8 *data);
+extern int bbm_byte_read(HANDLE hDevice, u16 addr, u8 *data);
+extern int bbm_word_read(HANDLE hDevice, u16 addr, u16 *data);
+extern int bbm_long_read(HANDLE hDevice, u16 addr, u32 *data);
+extern int bbm_bulk_read(HANDLE hDevice, u16 addr, u8 *data, u16 length);
+
+extern int bbm_write(HANDLE hDevice, u16 addr, u8 data);
+extern int bbm_byte_write(HANDLE hDevice, u16 addr, u8 data);
+extern int bbm_word_write(HANDLE hDevice, u16 addr, u16 data);
+extern int bbm_long_write(HANDLE hDevice, u16 addr, u32 data);
+extern int bbm_bulk_write(HANDLE hDevice, u16 addr, u8 *data, u16 length);
+extern int bbm_data(HANDLE hDevice, u16 addr, u8 *data, u16 length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/fc8100/fci_i2c.c b/drivers/media/isdbt/fc8100/fci_i2c.c
new file mode 100644
index 0000000..05c8dc9
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fci_i2c.c
@@ -0,0 +1,42 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fci_i2c.c
+
+ Description : fci i2c repeater mapping driver for RF register control
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/09/29 bruce initial
+*******************************************************************************/
+
+#include "fci_types.h"
+#include "fc8100_i2c.h"
+
+int fci_i2c_init (HANDLE hDevice, int speed, int slaveaddr)
+{
+ return BBM_OK;
+}
+
+int fci_i2c_deinit (HANDLE hDevice)
+{
+ return BBM_OK;
+}
+
+int fci_i2c_read(HANDLE hDevice, u8 chip, u8 addr, u8 alen, u8 *data, u8 len)
+{
+ int res = BBM_NOK;
+
+ res = fc8100_rf_bulkread(hDevice, addr, data, len);
+
+ return res;
+}
+
+int fci_i2c_write(HANDLE hDevice, u8 chip, u8 addr, u8 alen, u8 *data, u8 len)
+{
+ int res = BBM_NOK;
+
+ res = fc8100_rf_bulkwrite(hDevice, addr, data, len);
+
+ return res;
+}
diff --git a/drivers/media/isdbt/fc8100/fci_i2c.h b/drivers/media/isdbt/fc8100/fci_i2c.h
new file mode 100644
index 0000000..816a6fc
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fci_i2c.h
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fci_i2c.h
+
+ Description : fci i2c driver header
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/09/11 jason initial
+*******************************************************************************/
+
+#ifndef __FCI_I2C_H__
+#define __FCI_I2C_H__
+
+#include "fci_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int fci_i2c_init(HANDLE hDevice, int speed, int slaveaddr);
+extern int fci_i2c_deinit(HANDLE hDevice);
+extern int fci_i2c_read(HANDLE hDevice, u8 chip, u8 addr, u8 alen, u8 *data, u8 len);
+extern int fci_i2c_write(HANDLE hDevice, u8 chip, u8 addr, u8 alen, u8 *data, u8 len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/fc8100/fci_oal.c b/drivers/media/isdbt/fc8100/fci_oal.c
new file mode 100644
index 0000000..ba77ce6
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fci_oal.c
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fci_oal.c
+
+ Description : OS Adaptation Layer
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/09/13 jason initial
+*******************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+
+#include "fci_types.h"
+
+void PRINTF(HANDLE hDevice, char *fmt, ...)
+{
+ va_list ap;
+ char str[256];
+
+ va_start(ap, fmt);
+ vsprintf(str, fmt, ap);
+
+ printk("%s", str);
+
+ va_end(ap);
+}
+
+void msWait(int ms)
+{
+ msleep(ms);
+}
diff --git a/drivers/media/isdbt/fc8100/fci_oal.h b/drivers/media/isdbt/fc8100/fci_oal.h
new file mode 100644
index 0000000..557b21f
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fci_oal.h
@@ -0,0 +1,27 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fci_oal.h
+
+ Description : OS Adatation Layer header
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/09/13 jason initial
+*******************************************************************************/
+
+#ifndef __FCI_OAL_H__
+#define __FCI_OAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void PRINTF(HANDLE hDevice, char *fmt, ...);
+extern void msWait(int ms);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/fc8100/fci_tun.c b/drivers/media/isdbt/fc8100/fci_tun.c
new file mode 100644
index 0000000..f4cd5a5
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fci_tun.c
@@ -0,0 +1,162 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : tuner.c
+
+ Description : tuner driver
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/08/29 jason initial
+*******************************************************************************/
+
+#include "fci_types.h"
+#include "fci_oal.h"
+#include "fci_hal.h"
+#include "fci_tun.h"
+#include "fci_i2c.h"
+#include "fc8100_regs.h"
+#include "fc8100_tun.h"
+
+#define FC8100_TUNER_ADDR 0x56
+
+static u8 tuner_addr = FC8100_TUNER_ADDR;
+static band_type tuner_band = ISDBT_1_SEG_TYPE;
+
+typedef struct {
+ int (*init)(HANDLE hDevice, int speed, int slaveaddr);
+ int (*read)(HANDLE hDevice, u8 chip, u8 addr, u8 alen, u8 *data, u8 len);
+ int (*write)(HANDLE hDevice, u8 chip, u8 addr, u8 alen, u8 *data, u8 len);
+ int (*deinit)(HANDLE hDevice);
+} I2C_DRV;
+
+static I2C_DRV fcii2c = {
+ &fci_i2c_init,
+ &fci_i2c_read,
+ &fci_i2c_write,
+ &fci_i2c_deinit
+};
+
+typedef struct {
+ int (*init)(HANDLE hDevice, u8 band);
+ int (*set_freq)(HANDLE hDevice, u8 ch_num);
+ int (*get_rssi)(HANDLE hDevice, s32 *rssi);
+ int (*deinit)(HANDLE hDevice);
+} TUNER_DRV;
+
+static TUNER_DRV fc8100_tuner = {
+ &fc8100_tuner_init,
+ &fc8100_set_freq,
+ &fc8100_get_rssi,
+ &fc8100_tuner_deinit
+};
+
+static I2C_DRV *tuner_ctrl = &fcii2c;
+static TUNER_DRV *tuner = &fc8100_tuner;
+
+int tuner_ctrl_select(HANDLE hDevice, i2c_type type)
+{
+ int res = BBM_OK;
+
+ switch (type) {
+ case FCI_I2C_TYPE:
+ tuner_ctrl = &fcii2c;
+ break;
+ default:
+ res = BBM_NOK;
+ break;
+ }
+ if (res)
+ return BBM_NOK;
+
+ res = tuner_ctrl->init(hDevice, 400, 0);
+
+ return res;
+}
+
+int tuner_i2c_read(HANDLE hDevice, u8 addr, u8 alen, u8 *data, u8 len)
+{
+ int res = BBM_OK;
+
+ res = tuner_ctrl->read(hDevice, tuner_addr, addr, alen, data, len);
+
+ return res;
+}
+
+int tuner_i2c_write(HANDLE hDevice, u8 addr, u8 alen, u8 *data, u8 len)
+{
+ int res = BBM_OK;
+
+ res = tuner_ctrl->write(hDevice, tuner_addr, addr, alen, data, len);
+
+ return res;
+}
+
+int tuner_type(HANDLE hDevice, u32 *type)
+{
+ *type = tuner_band;
+
+ return BBM_OK;
+}
+
+int tuner_set_freq(HANDLE hDevice, u8 ch_num)
+{
+ int res = BBM_NOK;
+
+ if (tuner == NULL) {
+ PRINTF(NULL, "TUNER NULL ERROR \r\n");
+ return BBM_NOK;
+ }
+
+ res = tuner->set_freq(hDevice, ch_num);
+ if (res != BBM_OK) {
+ PRINTF(NULL, "TUNER res ERROR \r\n");
+ return BBM_NOK;
+ }
+
+ return res;
+}
+
+int tuner_select(HANDLE hDevice, u32 product, u32 band)
+{
+ int res = BBM_OK;
+
+ switch (product) {
+ case FC8100_TUNER:
+ tuner_band = band;
+ tuner_addr = FC8100_TUNER_ADDR;
+ tuner = &fc8100_tuner;
+ res = tuner_ctrl_select(hDevice, FCI_I2C_TYPE);
+ PRINTF(0, "FC8100 Tuner Select\n");
+ break;
+ default:
+ res = BBM_NOK;
+ break;
+ }
+
+ if (tuner == NULL || res) {
+ PRINTF(NULL, "[ERROR] Can not supported Tuner(%d,%d)\n\r", product, band);
+ return BBM_NOK;
+ }
+
+ res = tuner->init(hDevice, band);
+ PRINTF(NULL, "TUNER_SELECT(%s) \n\r", res == BBM_OK ? "SUCCESS" : "FAIL");
+
+ return res;
+}
+
+int tuner_deselect(HANDLE hDevice)
+{
+ int res = BBM_OK;
+
+ return res;
+}
+
+int tuner_get_rssi(HANDLE hDevice, s32 *rssi)
+{
+ int res = BBM_OK;
+
+ res = tuner->get_rssi(hDevice, rssi);
+
+ return res;
+}
diff --git a/drivers/media/isdbt/fc8100/fci_tun.h b/drivers/media/isdbt/fc8100/fci_tun.h
new file mode 100644
index 0000000..f4594f2
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fci_tun.h
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : tuner.h
+
+ Description : tuner control driver header
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/08/29 jason initial
+*******************************************************************************/
+
+#ifndef __TUNER_H__
+#define __TUNER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "fci_types.h"
+#include "bbm.h"
+
+typedef enum {
+ FCI_I2C_TYPE = 0,
+ ADI_I2C_TYPE
+} i2c_type;
+
+typedef enum {
+ BAND3_TYPE = 0,
+ LBAND_TYPE,
+ ISDBT_1_SEG_TYPE,
+ FM_TYPE
+} band_type;
+
+typedef enum {
+ FC8000_TUNER = 0,
+ FC2507_TUNER,
+ FC2580_TUNER,
+ FC8100_TUNER
+} product_type;
+
+
+extern int tuner_i2c_init(HANDLE hDevice, int speed, int slaveaddr);
+extern int tuner_i2c_read(HANDLE hDevice, u8 addr, u8 alen, u8 *data, u8 len);
+extern int tuner_i2c_write(HANDLE hDevice, u8 addr, u8 alen, u8 *data, u8 len);
+
+extern int tuner_select(HANDLE hDevice, u32 product, u32 band);
+extern int tuner_deselect(HANDLE hDevice);
+extern int tuner_set_freq(HANDLE hDevice, u8 ch_num);
+extern int tuner_get_rssi(HANDLE hDevice, s32 *rssi);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/fc8100/fci_types.h b/drivers/media/isdbt/fc8100/fci_types.h
new file mode 100644
index 0000000..b36626d
--- /dev/null
+++ b/drivers/media/isdbt/fc8100/fci_types.h
@@ -0,0 +1,46 @@
+/*****************************************************************************
+ Copyright(c) 2009 FCI Inc. All Rights Reserved
+
+ File name : fci_types.h
+
+ Description :
+
+ History :
+ ----------------------------------------------------------------------
+ 2009/08/31 jason initial
+*******************************************************************************/
+
+#ifndef __FCI_TYPES_H__
+#define __FCI_TYPES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef HANDLE
+typedef int HANDLE;
+#endif
+
+#define s8 char
+#define s16 short int
+#define s32 int
+
+#define u8 unsigned char
+#define u16 unsigned short
+#define u32 unsigned int
+
+#define TRUE 1
+#define FALSE 0
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define BBM_OK 0
+#define BBM_NOK 1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/media/isdbt/isdbt.c b/drivers/media/isdbt/isdbt.c
new file mode 100644
index 0000000..da08bc0
--- /dev/null
+++ b/drivers/media/isdbt/isdbt.c
@@ -0,0 +1,598 @@
+/************************************************************
+ * /drivers/media/isdbt/isdbt.c
+ *
+ * ISDBT DRIVER
+ *
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * http://www.samsung.com
+ *
+ ***********************************************************/
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/spi/spi.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <plat/gpio-cfg.h>
+#include <plat/s3c64xx-spi.h>
+#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
+#include "isdbt.h"
+
+#define SPI_FIND_HEADER_IN_BUFFER
+/* #define SPI_WRITE_BUF */
+
+#define DATA_PACKET_SIZE 188
+#define DATA_PACKET_CNT 128
+#define SPI_BURST_READ_SIZE (DATA_PACKET_SIZE * DATA_PACKET_CNT)
+#define SPI_DATA_FRAME_BUF (SPI_BURST_READ_SIZE * 10)
+
+#define SPI_READ_TIMEOUT (SPI_BURST_READ_SIZE/40 + 10)
+
+#define READ_PACKET_MARGIN (DATA_PACKET_SIZE/2)
+
+#define HEADER_OF_VALID_PACKET 0x47
+#define INVALID_PACKET_CHECK_CNT 3
+
+#define CS_INT_MODE() S3C_GPIO_SFN(0xf)
+#define CS_SPI_MODE() S3C_GPIO_SFN(0x2)
+
+#define SPIDEV_WARMUP_DELAY 300
+
+#define DEVICE_NAME "isdbtdata"
+
+typedef struct{
+ int index;
+ int init_info;
+ unsigned char *rBuf;
+ unsigned char *wBuf;
+ struct mutex buflock;
+ struct completion xfer_completion;
+ struct completion overflow_completion;
+ long xfer_size;
+ int xfer_result;
+ struct class *isdbt_class;
+ struct device *isdbt_debug_dev;
+ struct spi_device *spidev;
+ unsigned char *RingBuf;
+ long ring_buf_wr_pos;
+ long ring_buf_rd_pos;
+ int buf_over_flow;
+ struct workqueue_struct *read_workqueue;
+ struct work_struct work_read_spi;
+ unsigned long pkt_err_cnt;
+} isdbt_spi_info;
+
+static isdbt_spi_info *isdbt_data;
+
+static ssize_t isdbt_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ isdbt_spi_info *pdev = dev_get_drvdata(dev);
+ int result = 0;
+
+ if (pdev->init_info == 0)
+ result = 0;
+ else
+ result = 1;
+
+ return sprintf(buf, " %s \n wr_pos : [ %lx ]\n rd_pos : [ %lx ] \n pkt_err_cnt [ %lx ]\n",
+ (result & 1) ? "active" : "deactive", pdev->ring_buf_wr_pos,
+ pdev->ring_buf_rd_pos, pdev->pkt_err_cnt);
+}
+static DEVICE_ATTR(isdbt_status, 0666, isdbt_status_show, NULL);
+
+
+static int fc8100_spi_read(struct spi_device *spidev, u8 *buf, size_t len)
+{
+ struct spi_message msg;
+ struct spi_transfer transfer;
+ int status = 0;
+ int result = 0;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&transfer, 0, sizeof(transfer));
+
+ spi_message_init(&msg);
+ msg.spi = spidev;
+
+ transfer.tx_buf = (unsigned char *)NULL;
+ transfer.rx_buf = (unsigned char *)buf;
+ transfer.len = len;
+ transfer.bits_per_word = 8;
+ transfer.delay_usecs = 0;
+
+ spi_message_add_tail(&transfer, &msg);
+ status = spi_sync(spidev, &msg);
+
+ if (status == 0)
+ result = msg.actual_length;
+ else
+ result = status;
+
+ return result;
+}
+
+
+
+static int fc8100_spi_write(struct spi_device *spidev, u8 *buf, size_t len)
+{
+ struct spi_message msg;
+ struct spi_transfer transfer;
+ int status = 0;
+ int result = 0;
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&transfer, 0, sizeof(transfer));
+
+ spi_message_init(&msg);
+ msg.spi = spidev;
+
+ transfer.tx_buf = (unsigned char *)buf;
+ transfer.rx_buf = (unsigned char *)NULL;
+ transfer.len = len;
+ transfer.bits_per_word = 8;
+ transfer.delay_usecs = 0;
+
+ spi_message_add_tail(&transfer, &msg);
+ status = spi_sync(spidev, &msg);
+
+ if (status == 0)
+ result = msg.actual_length;
+ else
+ result = status;
+
+ return result;
+}
+
+static int fc8100_spi_probe(struct spi_device *spi)
+{
+ int ret = -EINVAL;
+ isdbt_spi_info *pdev;
+
+ pdev = kmalloc(sizeof(isdbt_spi_info), GFP_KERNEL);
+ if (pdev == NULL) {
+ I_DEV_DBG(" memory allocation failed ");
+ ret = -ENOMEM;
+ goto done;
+ }
+ memset(pdev, 0, sizeof(isdbt_spi_info));
+
+ pdev->isdbt_class = class_create(THIS_MODULE, "isdbt");
+ if (IS_ERR(pdev->isdbt_class)) {
+ I_DEV_DBG(" could not create isdbt_class");
+ goto err_class_create;
+ }
+
+ pdev->isdbt_debug_dev = device_create(pdev->isdbt_class,
+ NULL, 0, NULL, "isdbt_status");
+ if (IS_ERR(pdev->isdbt_debug_dev)) {
+ I_DEV_DBG(" could not create isdbt_status file");
+ goto err_device_create;
+ }
+
+ if (device_create_file(pdev->isdbt_debug_dev,
+ &dev_attr_isdbt_status) < 0) {
+ I_DEV_DBG(" could not create device file(%s)",
+ dev_attr_isdbt_status.attr.name);
+ goto err_device_create_file;
+ }
+
+ pdev->spidev = spi;
+ pdev->spidev->mode = (SPI_MODE_0|SPI_CS_HIGH);
+ pdev->spidev->bits_per_word = 8;
+
+ dev_set_drvdata(pdev->isdbt_debug_dev, pdev);
+
+ ret = spi_setup(pdev->spidev);
+
+ spi_set_drvdata(spi, pdev);
+ isdbt_data = pdev;
+
+ I_DEV_DBG("Probe %s ,[ %d ]", (ret & 1) ? "ERROR" : "SUCCESS" , ret);
+ goto done;
+
+err_device_create_file:
+ device_destroy(pdev->isdbt_class, 0);
+err_device_create:
+ class_destroy(pdev->isdbt_class);
+err_class_create:
+ kfree(pdev);
+done:
+ return ret;
+}
+
+static int fc8100_spi_remove(struct spi_device *spi)
+{
+ isdbt_spi_info *pdev = spi_get_drvdata(spi);
+
+ device_destroy(pdev->isdbt_class, 0);
+ class_destroy(pdev->isdbt_class);
+ kfree(pdev);
+ isdbt_data = NULL;
+ I_DEV_DBG("");
+ return 0;
+}
+
+static struct spi_driver fc8100_spi_driver = {
+ .driver = {
+ .name = "isdbtspi",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = fc8100_spi_probe,
+ .remove = __devexit_p(fc8100_spi_remove),
+};
+
+static int fc8100_spi_driver_init(void)
+{
+ int ret = 0;
+
+ ret = spi_register_driver(&fc8100_spi_driver);
+
+ I_DEV_DBG("FC8100 SPI DRIVER %s , ret = [ %d ]",
+ (ret & 1) ? "ERROR" : " INIT ", ret);
+
+ return ret;
+}
+
+static void fc8100_spi_exit(void)
+{
+ I_DEV_DBG("");
+ spi_unregister_driver(&fc8100_spi_driver);
+ return;
+}
+
+static void IsValied_packet_check(isdbt_spi_info *pdev)
+{
+ int cnt = 0;
+
+ /* Find Header */
+ while (1) {
+ if ((pdev->rBuf[cnt] == HEADER_OF_VALID_PACKET)
+ && (pdev->rBuf[cnt + DATA_PACKET_SIZE] == HEADER_OF_VALID_PACKET)
+ && (pdev->rBuf[cnt + (DATA_PACKET_SIZE*2)] == HEADER_OF_VALID_PACKET)) {
+ break;
+ }
+
+ if (cnt > READ_PACKET_MARGIN) {
+ pdev->pkt_err_cnt++;
+ I_DEV_DBG(" FIND ====== ERROR cnt = %d, pkt_err_cnt = %d ",
+ cnt, pdev->pkt_err_cnt);
+ pdev->xfer_result = -EINVAL;
+ break;
+ }
+ cnt++;
+ }
+
+ if (pdev->xfer_result == pdev->xfer_size) {
+ mutex_lock(&pdev->buflock);
+ if (pdev->ring_buf_wr_pos + cnt > SPI_DATA_FRAME_BUF) {
+ pdev->ring_buf_wr_pos = 0;
+ pdev->buf_over_flow = 1;
+ complete(&pdev->overflow_completion);
+ }
+ memcpy(&pdev->RingBuf[pdev->ring_buf_wr_pos],
+ &pdev->rBuf[cnt], pdev->xfer_result);
+ pdev->ring_buf_wr_pos += pdev->xfer_result;
+ pdev->index = 1;
+ mutex_unlock(&pdev->buflock);
+ complete(&pdev->xfer_completion);
+ }
+
+ return;
+}
+
+void isdbt_work_queue_spi_read_buf(struct work_struct *work)
+{
+ isdbt_spi_info *pdev = container_of(work, isdbt_spi_info, work_read_spi);
+ struct s3c64xx_spi_csinfo *cs = pdev->spidev->controller_data;
+
+ disable_irq(gpio_to_irq(cs->line));
+ s3c_gpio_cfgpin(cs->line, CS_SPI_MODE());
+ udelay(SPIDEV_WARMUP_DELAY);
+ INIT_COMPLETION(pdev->xfer_completion);
+ pdev->xfer_size = SPI_BURST_READ_SIZE + READ_PACKET_MARGIN ;
+ pdev->xfer_result = fc8100_spi_read(pdev->spidev,
+ pdev->rBuf, pdev->xfer_size);
+ pdev->xfer_size -= READ_PACKET_MARGIN;
+ pdev->xfer_result -= READ_PACKET_MARGIN;
+
+ s3c_gpio_cfgpin(cs->line, CS_INT_MODE());
+ enable_irq(gpio_to_irq(cs->line));
+
+ if ((pdev->xfer_result != pdev->xfer_size)
+ || (pdev->xfer_result < DATA_PACKET_SIZE*INVALID_PACKET_CHECK_CNT)) {
+ I_DEV_DBG(" Packet read failed = %d", pdev->xfer_result);
+ pdev->xfer_result = -EINVAL;
+ } else {
+ IsValied_packet_check(pdev);
+ }
+
+ return;
+}
+
+
+static irqreturn_t isdbt_read_data_threaded_irq(int irq, void *data)
+{
+ isdbt_spi_info *pdev = (isdbt_spi_info *)(data);
+ queue_work(pdev->read_workqueue, &pdev->work_read_spi);
+ return IRQ_HANDLED;
+}
+
+static int isdbt_open(struct inode *inode, struct file *filp)
+{
+ int status = 0;
+ isdbt_spi_info *pdev;
+ struct s3c64xx_spi_csinfo *cs;
+ I_DEV_DBG("");
+
+ pdev = isdbt_data;
+
+ if (pdev->init_info == 1) {
+ I_DEV_DBG("Already open....");
+ return status;
+ }
+
+ pdev->index = 0;
+ pdev->ring_buf_wr_pos = 0;
+ pdev->ring_buf_rd_pos = 0;
+ pdev->buf_over_flow = 0;
+
+ cs = pdev->spidev->controller_data;
+
+ pdev->rBuf = kmalloc(SPI_BURST_READ_SIZE+(DATA_PACKET_SIZE*5), GFP_KERNEL);
+ if (pdev->rBuf == NULL) {
+ I_DEV_DBG(" rBuf :: kamlloc failed");
+ status = -ENOMEM;
+ goto err_malloc_rBuf;
+ }
+ pdev->RingBuf = vmalloc(SPI_DATA_FRAME_BUF);
+ if (pdev->RingBuf == NULL) {
+ I_DEV_DBG(" ring buf :: malloc failed");
+ status = -ENOMEM;
+ goto err_malloc_ringbuf;
+ }
+#if defined(SPI_WRITE_BUF)
+ pdev->wBuf = kmalloc(SPI_BURST_READ_SIZE+(DATA_PACKET_SIZE*5), GFP_KERNEL);
+ if (pdev->wBuf == NULL) {
+ I_DEV_DBG(" wBuf :: kmalloc failed");
+ status = -ENOMEM;
+ goto err_malloc_wBuf;
+ }
+#endif
+ filp->private_data = pdev;
+ mutex_init(&pdev->buflock);
+
+ pdev->read_workqueue = create_singlethread_workqueue("isdbtd");
+ if (pdev->read_workqueue == 0) {
+ I_DEV_DBG(" ERROR : register workqueue");
+ goto err_register_queue;
+ }
+ INIT_WORK(&pdev->work_read_spi, isdbt_work_queue_spi_read_buf);
+
+ init_completion(&pdev->xfer_completion);
+ init_completion(&pdev->overflow_completion);
+
+ status = request_threaded_irq(gpio_to_irq(cs->line), NULL,
+ isdbt_read_data_threaded_irq, IRQF_DISABLED, "isdbt_irq", pdev);
+ if (status != 0) {
+ I_DEV_DBG(" ERROR : request_threaded_irq failed = [ %d ]", status);
+ I_DEV_DBG("filp private_data=0x%x. ", (unsigned int)filp->private_data);
+ status = -EINVAL;
+ goto err_register_isr;
+ }
+ disable_irq(gpio_to_irq(cs->line));
+ s3c_gpio_cfgpin(cs->line, CS_INT_MODE());
+ set_irq_type(gpio_to_irq(cs->line), IRQ_TYPE_EDGE_RISING);
+
+ I_DEV_DBG("");
+ s3c_gpio_cfgpin(cs->line, CS_INT_MODE());
+ enable_irq(gpio_to_irq(cs->line));
+
+ status = 0;
+ goto done;
+err_register_isr:
+ free_irq(gpio_to_irq(cs->line), pdev);
+ flush_workqueue(pdev->read_workqueue);
+#if defined(SPI_WRITE_BUF)
+ kfree(pdev->wBuf);
+#endif
+err_register_queue:
+ destroy_workqueue(pdev->read_workqueue);
+#if defined(SPI_WRITE_BUF)
+err_malloc_wBuf:
+ pdev->wBuf = NULL;
+#endif
+ vfree(pdev->RingBuf);
+err_malloc_ringbuf:
+ pdev->RingBuf = NULL;
+ kfree(pdev->rBuf);
+err_malloc_rBuf:
+ pdev->rBuf = NULL;
+done:
+ if (status == 0)
+ pdev->init_info = 1;
+ return status;
+}
+
+static int isdbt_release(struct inode *inode, struct file *filp)
+{
+ isdbt_spi_info *pdev = (isdbt_spi_info *)(filp->private_data);
+ struct s3c64xx_spi_csinfo *cs = pdev->spidev->controller_data;
+
+ if (pdev->init_info == 0) {
+ I_DEV_DBG(" Already release... ");
+ return 0;
+ }
+
+ cancel_work_sync(&pdev->work_read_spi);
+ free_irq(gpio_to_irq(cs->line), pdev);
+
+ flush_work(&pdev->work_read_spi);
+ flush_workqueue(pdev->read_workqueue);
+ destroy_workqueue(pdev->read_workqueue);
+
+ vfree(pdev->RingBuf);
+ pdev->RingBuf = NULL;
+
+#if defined(SPI_WRITE_BUF)
+ kfree(pdev->wBuf);
+#endif
+ pdev->wBuf = NULL;
+
+ kfree(pdev->rBuf);
+ pdev->rBuf = NULL;
+
+ pdev->init_info = 0;
+ return 0;
+}
+
+static int isdbt_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+{
+ int result = 0;
+ int status = 0;
+ int unused_packet = 0;
+
+ unsigned long timeout = 0;
+ isdbt_spi_info *pdev = (isdbt_spi_info *)(filp->private_data);
+
+ if (pdev->index == 0) {
+ msleep(100);
+ return -EIO;
+ }
+
+ if (pdev->ring_buf_rd_pos+count <= SPI_DATA_FRAME_BUF) {
+ if (pdev->buf_over_flow == 0) {
+ if (pdev->ring_buf_rd_pos+count > pdev->ring_buf_wr_pos) {
+ timeout = wait_for_completion_timeout(&pdev->xfer_completion,
+ msecs_to_jiffies(SPI_READ_TIMEOUT));
+ I_DEV_DBG(" xfer timeout = %ld ", timeout);
+ if (timeout == 0)
+ result = -ETIMEDOUT;
+ }
+ }
+ } else {
+ if (!pdev->buf_over_flow) {
+ wait_for_completion_timeout(&pdev->overflow_completion,
+ msecs_to_jiffies(SPI_READ_TIMEOUT));
+ INIT_COMPLETION(pdev->overflow_completion);
+ I_DEV_DBG(" overflow timeout = %ld ", timeout);
+ if (timeout == 0)
+ result = -ETIMEDOUT;
+ }
+
+ pdev->buf_over_flow = 0;
+ pdev->ring_buf_rd_pos = 0;
+ if (pdev->ring_buf_rd_pos+count > pdev->ring_buf_wr_pos) {
+ wait_for_completion_timeout(&pdev->xfer_completion,
+ msecs_to_jiffies(SPI_READ_TIMEOUT));
+ I_DEV_DBG(" over xfer timeout = %ld ", timeout);
+ if (timeout == 0)
+ result = -ETIMEDOUT;
+ }
+ }
+
+ unused_packet = pdev->ring_buf_wr_pos - pdev->ring_buf_rd_pos+count;
+ if (pdev->buf_over_flow)
+ unused_packet += SPI_DATA_FRAME_BUF;
+
+ if (result == 0) {
+ mutex_lock(&pdev->buflock);
+ status = copy_to_user(buf, &pdev->RingBuf[pdev->ring_buf_rd_pos], count);
+ if (status < 0) {
+ I_DEV_DBG(" copy user failed ");
+ result = -EFAULT;
+ } else {
+ result = count;
+ pdev->ring_buf_rd_pos += result;
+ }
+ mutex_unlock(&pdev->buflock);
+ if ((SPI_DATA_FRAME_BUF/5) < unused_packet) {
+ msleep(40);
+ I_DEV_DBG(" read write gap : %d ", unused_packet);
+ } else
+ msleep(80);
+ }
+ I_DEV_DBG(" rd pos %lx , unused %x", pdev->ring_buf_rd_pos, unused_packet);
+
+ return result;
+}
+
+static ssize_t isdbt_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
+{
+ int result = 0;
+ int status = 0;
+ isdbt_spi_info *pdev = (isdbt_spi_info *)(filp->private_data);
+
+ mutex_lock(&pdev->buflock);
+
+ status = copy_from_user(pdev->wBuf, buf, count);
+ if (status < 0) {
+ I_DEV_DBG(" copy user failed ");
+ result = -EINVAL;
+ }
+
+ result = fc8100_spi_write(pdev->spidev, pdev->wBuf, count);
+
+ if (result < 0)
+ I_DEV_DBG(" write failed = %d ", result);
+
+ mutex_unlock(&pdev->buflock);
+
+ return result;
+}
+
+
+static struct file_operations isdbt_spi_fops = {
+ .owner = THIS_MODULE,
+ .open = isdbt_open,
+ .release = isdbt_release,
+ .read = isdbt_read,
+ .write = isdbt_write,
+};
+
+static struct miscdevice isdbt_spi_misc_dev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = DEVICE_NAME,
+ .fops = &isdbt_spi_fops,
+};
+
+static int __init isdbt_spi_init(void)
+{
+ int ret = 0;
+
+ I_DEV_DBG("");
+
+ ret = misc_register(&isdbt_spi_misc_dev);
+
+ if (ret < 0)
+ I_DEV_DBG(" ERROR ");
+ else
+ ret = fc8100_spi_driver_init();
+
+ return ret;
+}
+module_init(isdbt_spi_init);
+
+static void __exit isdbt_spi_exit(void)
+{
+ I_DEV_DBG("");
+ fc8100_spi_exit();
+ misc_deregister(&isdbt_spi_misc_dev);
+}
+module_exit(isdbt_spi_exit);
+
+MODULE_DESCRIPTION(" ISDBT DRIVER - FC8100 ");
+MODULE_AUTHOR("xmoondash");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/isdbt/isdbt.h b/drivers/media/isdbt/isdbt.h
new file mode 100644
index 0000000..cc56503
--- /dev/null
+++ b/drivers/media/isdbt/isdbt.h
@@ -0,0 +1,26 @@
+/************************************************************
+ * /drivers/media/isdbt/isdbt.c
+ *
+ * ISDBT DRIVER
+ *
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * http://www.samsung.com
+ *
+ ***********************************************************/
+#ifndef __ISDBT_H__
+#define __ISDBT_H__
+
+/* #define DEBUG_MSG_SPI */
+
+#ifdef DEBUG_MSG_SPI
+#define SUBJECT "ISDBT-SPI-DRIVER"
+#define I_DEV_DBG(format, ...) \
+ printk("[ "SUBJECT " (%s,%d) ] " format "\n", __func__, __LINE__, ## __VA_ARGS__)
+
+#else
+#define I_DEV_DBG(format, ...)
+#endif
+
+#endif