diff options
author | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
---|---|---|
committer | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
commit | c6da2cfeb05178a11c6d062a06f8078150ee492f (patch) | |
tree | f3b4021d252c52d6463a9b3c1bb7245e399b009c /drivers/media/isdbt | |
parent | c6d7c4dbff353eac7919342ae6b3299a378160a6 (diff) | |
download | kernel_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')
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 |