diff options
author | Oliver Schinagl <oliver@schinagl.nl> | 2011-06-28 13:40:27 (GMT) |
---|---|---|
committer | Oliver Schinagl <oliver@schinagl.nl> | 2011-06-28 13:40:27 (GMT) |
commit | fecdd9457cd3912c2b89aff1f99db0ba669af93b (patch) | |
tree | 34bbc7387ded825e303c3117b6c6da2cbe1fd771 /src | |
download | AF903x_SRC-fecdd9457cd3912c2b89aff1f99db0ba669af93b.zip AF903x_SRC-fecdd9457cd3912c2b89aff1f99db0ba669af93b.tar.gz AF903x_SRC-fecdd9457cd3912c2b89aff1f99db0ba669af93b.tar.bz2 |
Initial checkin' of sourceball extracted from installer.
DRIVER_RELEASE_VERSION : v9.08.14.1
FW_RELEASE_VERSION : v8_8_63_0
API_RELEASE_VERSION : 200.20090402.0
Not sure what those version numbers relate to.
Might be Driver, the actual driver (src)
FW, the little bin file that is only a keymapping for the remote
API, all the tuners or so from /api?
No support for Asus U3100
mini (yet).
Diffstat (limited to 'src')
-rw-r--r-- | src/af903x-core.c | 126 | ||||
-rw-r--r-- | src/af903x-devices.c | 214 | ||||
-rw-r--r-- | src/af903x-drv.c | 1579 | ||||
-rw-r--r-- | src/af903x-fe.c | 249 | ||||
-rw-r--r-- | src/af903x-ioctl.h | 29 | ||||
-rw-r--r-- | src/af903x-tuner.c | 92 | ||||
-rw-r--r-- | src/af903x.h | 225 | ||||
-rw-r--r-- | src/userdef.h | 24 |
8 files changed, 2538 insertions, 0 deletions
diff --git a/src/af903x-core.c b/src/af903x-core.c new file mode 100644 index 0000000..cf69d6a --- /dev/null +++ b/src/af903x-core.c @@ -0,0 +1,126 @@ +#include "af903x.h" + +DEVICE_CONTEXT DC; +bool TunerInited0, TunerInited1, DeviceReboot; +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +static int af903x_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + int retval = -ENOMEM; + int i; + + deb_data("===af903x usb device pluged in!! ===\n"); + retval = Device_init(interface_to_usbdev(intf),&DC, true); + if (retval){ + if(retval) deb_data("Device_init Fail: 0x%08x\n", retval); + return retval; + } + + if ( af903x_device_count > 2) + af903x_device_count = 2; + + for (i = 0; i < af903x_device_count; i++) + { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) + if (DC.architecture == Architecture_PIP) + af903x_properties[i].num_adapters = 2; +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25) + if (dvb_usb_device_init(intf, &af903x_properties[i], THIS_MODULE, NULL) == 0) + {deb_data("dvb_usb_device_init success!!\n");return 0;} +#else + if (dvb_usb_device_init(intf, &af903x_properties[i], THIS_MODULE, NULL,adapter_nr) == 0) + {deb_data("dvb_usb_device_init success!!\n");return 0;} +#endif + } + + return -ENOMEM; +} +static int af903x_suspend(struct usb_interface *intf, u32 state) +{ + int error; + deb_data("Enter %s Function\n",__FUNCTION__); + +#ifdef EEEPC + error = DL_Reboot(); +#else + if (DevicePower) + { + error = DL_CheckTunerInited(0, &TunerInited0); + error = DL_CheckTunerInited(1, &TunerInited1); + + error = DL_ApCtrl(0, 0); + error = DL_ApCtrl(1, 0); + if (error) {deb_data("DL_ApCtrl error : 0x%x\n", error);} + + DeviceReboot = true; + } +#endif + return 0; +} + +static int af903x_resume(struct usb_interface *intf) +{ + int retval = -ENOMEM; + int error; + deb_data("Enter %s Function\n",__FUNCTION__); + +#ifdef EEEPC +#else + if(DeviceReboot == true) + { + retval = Device_init(interface_to_usbdev(intf),&DC, false); + if (retval) + if(retval) deb_data("Device_init Fail: 0x%08x\n", retval); + + if (TunerInited0) + error = DL_ApCtrl(0, 1); + if (TunerInited1) + error = DL_ApCtrl(1, 1); + } +#endif + return 0; +} + + +static struct usb_driver af903x_driver = { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, +#endif + .name = "dvb_usb_af903x", + .probe = af903x_probe, + .disconnect = dvb_usb_device_exit, + .id_table = af903x_usb_id_table, +// .suspend = af903x_suspend, +// .resume = af903x_resume, +}; + +static int __init af903x_module_init(void) +{ + int result; + + info("%s",__FUNCTION__); + deb_data("dvb_usb_af903x Module is loaded \n"); + + if ((result = usb_register(&af903x_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + return 0; +} + +static void __exit af903x_module_exit(void) +{ + deb_data("dvb_usb_af903x Module is unloaded!\n"); + usb_deregister(&af903x_driver); +} + +module_init (af903x_module_init); +module_exit (af903x_module_exit); + +MODULE_AUTHOR("Jimmy Chen <JyunYu.Chen@ite.com.tw>"); +MODULE_DESCRIPTION("Driver for devices based on ITEtech AF903X"); +MODULE_VERSION(DRIVER_RELEASE_VERSION); +MODULE_LICENSE("GPL"); diff --git a/src/af903x-devices.c b/src/af903x-devices.c new file mode 100644 index 0000000..99f5c9e --- /dev/null +++ b/src/af903x-devices.c @@ -0,0 +1,214 @@ +#include "af903x.h" + +bool DevicePower; +static int af903x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) +{ + int ret =0; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) + deb_data("%s: onoff:%d\n", __func__, onoff); + + if ( PDC->fc[adap->id].bEnPID != onoff ) + DL_ResetPID((BYTE)adap->id); + + PDC->fc[adap->id].bEnPID = onoff; + + DL_PIDOnOff((BYTE)adap->id,onoff); +#endif + + return ret; +} + +static int af903x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pidnum, + int onoff) +{ + int ret = 0; + #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) + Pid pid; + deb_data("- %s: set pid filter, index %d, pid %x, onoff %d, now_onoff %d.\n", + __func__, index, pidnum, onoff, PDC->fc[adap->id].bEnPID); + + if (onoff && !PDC->fc[adap->id].bEnPID) + { + DL_ResetPID((BYTE)adap->id); + PDC->fc[adap->id].bEnPID = onoff; + DL_PIDOnOff((BYTE)adap->id,onoff); + pid.sectionType = SectionType_TABLE; + pid.table = 0x00; + pid.duration = 0xFF; + } + + pid.value = (Word)pidnum; + if (onoff){ + ret = DL_AddPID((BYTE)adap->id, index, pid); + }else{ + ret = DL_RemovePID((BYTE)adap->id, index, pid); + } +#endif + + return ret; +} + +static int af903x_download_firmware(struct usb_device *udev, const struct firmware *fw) +{ + int ret=0; + deb_data("- Enter %s Function -\n",__FUNCTION__); + + return ret; +} + +static int af903x_powerctrl(struct dvb_usb_device *d, int onoff) +{ + + int ret; + DevicePower = onoff; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) + deb_data("- Enter %s Function - chip=%d:%s\n",__FUNCTION__, d->adapter->id, onoff?"ON":"OFF"); + ret = DL_ApCtrl(d->adapter->id, onoff); +#else + deb_data("- Enter %s Function - %s\n",__FUNCTION__, onoff?"ON":"OFF"); + ret = DL_ApCtrl(0, onoff); +#endif + if(ret) deb_data(" af903x_powerctrl Fail: 0x%04X\n", ret); + + return ret; +} + +static int af903x_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, int *cold) +{ + deb_data("- Enter %s Function -\n",__FUNCTION__); + *cold = 0; + + return 0; +} + +static int af903x_frontend_attach(struct dvb_usb_adapter *adap) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) + deb_data("- Enter %s Function - chip=%d\n", __FUNCTION__, adap->id); +#else + deb_data("- Enter %s Function - \n", __FUNCTION__); +#endif + adap->fe = af903x_attach(1); + + return adap->fe == NULL ? -ENODEV : 0; +} + +static int af903x_tuner_attach(struct dvb_usb_adapter *adap) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) + deb_data("- Enter %s Function - chip=%d\n",__FUNCTION__, adap->id); +#else + deb_data("- Enter %s Function - \n", __FUNCTION__); +#endif + tuner_attach(adap->fe); + return 0; +} + +static int af903x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) + deb_data("- Enter %s Function - (%s) streaming state for chip=%d\n",__FUNCTION__, onoff?"ON":"OFF", adap->id); + //PID off + DL_ResetPID((BYTE)adap->id); + PDC->fc[adap->id].bEnPID = 0; + DL_PIDOnOff((BYTE)adap->id,0); +#else + deb_data("- Enter %s Function - (%s) streaming state \n",__FUNCTION__, onoff?"ON":"OFF"); +#endif + + return 0; +} + +struct usb_device_id af903x_usb_id_table[] = { + { USB_DEVICE(0x15A4,0x1000) }, + { USB_DEVICE(0x15A4,0x1001) }, + { USB_DEVICE(0x15A4,0x1002) }, + { USB_DEVICE(0x15A4,0x1003) }, + { USB_DEVICE(0x15A4,0x9035) }, + { 0}, /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, af903x_usb_id_table); + +struct dvb_usb_device_properties af903x_properties[] = { + { + .usb_ctrl = DEVICE_SPECIFIC, + .download_firmware = af903x_download_firmware, + .no_reconnect = 1, + .power_ctrl = af903x_powerctrl, + .identify_state = af903x_identify_state, + +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING, + .pid_filter_count = 32, + .frontend_attach = af903x_frontend_attach, + .tuner_attach = af903x_tuner_attach, + .streaming_ctrl = af903x_streaming_ctrl, + .urb = { + .type = DVB_USB_BULK, + .count = 10, + .endpoint = 0x84, + .u = { + .bulk = { + .buffersize = 65424, + } + } + }, +#else + .num_adapters = 1, + .adapter = { + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = af903x_pid_filter, + .pid_filter_ctrl = af903x_pid_filter_ctrl, + .frontend_attach = af903x_frontend_attach, + .tuner_attach = af903x_tuner_attach, + .streaming_ctrl = af903x_streaming_ctrl, + .stream = { + .type = USB_BULK, + .count = 4, + .endpoint = 0x84, + .u = { + .bulk = { + .buffersize = 65424, + } + } + } + }, + { + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, + .pid_filter_count = 32, + .pid_filter = af903x_pid_filter, + .pid_filter_ctrl = af903x_pid_filter_ctrl, + .frontend_attach = af903x_frontend_attach, + .tuner_attach = af903x_tuner_attach, + .streaming_ctrl = af903x_streaming_ctrl, + .stream = { + .type = USB_BULK, + .count = 4, + .endpoint = 0x85, + .u = { + .bulk = { + .buffersize = 65424, + } + } + } + }, + }, +#endif + .num_device_descs =1, + .devices = { + { "ITEtech USB2.0 DVB-T Recevier", + { &af903x_usb_id_table[0], &af903x_usb_id_table[1],&af903x_usb_id_table[2], + &af903x_usb_id_table[3], &af903x_usb_id_table[4], NULL}, + { NULL }, + }, + {NULL}, + + } + } +}; + +int af903x_device_count = ARRAY_SIZE(af903x_properties); diff --git a/src/af903x-drv.c b/src/af903x-drv.c new file mode 100644 index 0000000..6ba44bf --- /dev/null +++ b/src/af903x-drv.c @@ -0,0 +1,1579 @@ +#include "af903x.h" + +#define FW_VER 0x08060000 +int dvb_usb_af903x_debug; +module_param_named(debug,dvb_usb_af903x_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level.(info=1,deb_fw=2,deb_fwdata=4,deb_data=8)" DVB_USB_DEBUG_STATUS); + +struct usb_device *udevs; +PDEVICE_CONTEXT PDC; + +static DEFINE_MUTEX(mymutex); + +//************** DRV_ *************// + +static DWORD DRV_IrTblDownload(IN void * handle) +{ + DWORD dwError = Error_NO_ERROR; + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + struct file *filp; + unsigned char b_buf[512] ; + int i, fileSize; + mm_segment_t oldfs; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + oldfs=get_fs(); + set_fs(KERNEL_DS); + + filp=filp_open("/lib/firmware/af35irtbl.bin", O_RDWR,0644); + if ( IS_ERR(filp) ) { + deb_data(" LoadIrTable : Can't open file\n");goto exit;} + + if ( (filp->f_op) == NULL ) { + deb_data(" LoadIrTable : File Operation Method Error!!\n");goto exit;} + + filp->f_pos=0x00; + fileSize = filp->f_op->read(filp,b_buf,sizeof(b_buf),&filp->f_pos); + + for(i=0; i<fileSize; i++) + { + //deb_data("\n Data %d",i); // + //deb_data("0x%x",b_buf[i]);// + // dwError = Af901xWriteReg(ucDemod2WireAddr, 0, MERC_IR_TABLE_BASE_ADDR + i, b_buf[i]); + //if (dwError) goto exit; + } + + dwError = Demodulator_loadIrTable((Demodulator*) &pdc->Demodulator, (Word)fileSize, b_buf); + if (dwError) {deb_data("Demodulator_loadIrTable fail"); goto exit;} + + filp_close(filp, NULL); + set_fs(oldfs); + + return (dwError); +exit: + deb_data("LoadIrTable fail!\n"); + +} + +static DWORD DRV_GetEEPROMConfig2( + void * handle, + BYTE ucSlaveDemod) +{ + + DWORD dwError = Error_NO_ERROR; + tWORD shift = 0; + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + BYTE btmp = 0; + + deb_data("- Enter %s Function -",__FUNCTION__); + + if(ucSlaveDemod) shift = EEPROM_SHIFT; + + dwError = Demodulator_readRegisters((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, EEPROM_TUNERID+shift, 1, &btmp); + if (dwError) goto exit; + deb_data("EEPROM_TUNERID%d = 0x%02X\n", ucSlaveDemod, btmp); + PTI.TunerId = btmp; + +exit: + + return(dwError); +} + +static DWORD DRV_SetFreqBw( + void* handle, + BYTE ucSlaveDemod, + DWORD dwFreq, + WORD ucBw +) +{ + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + Bool bLock = true; + + deb_data("- Enter %s Function -\n ",__FUNCTION__); + deb_data(" ucSlaveDemod = %d, Freq= %d, BW=%d\n", ucSlaveDemod, dwFreq, ucBw); + + if (pdc->fc[ucSlaveDemod].bEnPID) + { + Demodulator_resetPid((Demodulator*) &pdc->Demodulator, ucSlaveDemod); + //Disable PID filter + Demodulator_writeRegisterBits ((Demodulator*) &pdc->Demodulator, ucSlaveDemod, Processor_OFDM, p_mp2if_pid_en, mp2if_pid_en_pos, mp2if_pid_en_len, 0); + pdc->fc[ucSlaveDemod].bEnPID = 0; + } + + PTI.bSettingFreq = true; //before acquireChannel, it is ture; otherwise, it is false + + if(dwFreq) { + pdc->fc[ucSlaveDemod].ulDesiredFrequency = dwFreq; + } + else { + dwFreq = pdc->fc[ucSlaveDemod].ulDesiredFrequency; + } + + if(ucBw) { + pdc->fc[ucSlaveDemod].ucDesiredBandWidth = ucBw*1000; + } + else { + ucBw = pdc->fc[ucSlaveDemod].ucDesiredBandWidth; + } + + deb_data(" Real Freq= %d, BW=%d\n", pdc->fc[ucSlaveDemod].ulDesiredFrequency, pdc->fc[ucSlaveDemod].ucDesiredBandWidth); + + + if(!PTI.bTunerInited){ + deb_data(" Skip SetFreq - Tuner is still off!\n"); + goto exit; + } + + PTI.bTunerOK = false; + + if (pdc->fc[ucSlaveDemod].ulDesiredFrequency!=0 && pdc->fc[ucSlaveDemod].ucDesiredBandWidth!=0) + { + deb_data(" AcquireChannel : Real Freq= %d, BW=%d\n", pdc->fc[ucSlaveDemod].ulDesiredFrequency, pdc->fc[ucSlaveDemod].ucDesiredBandWidth); + dwError = Demodulator_acquireChannel ((Demodulator*) &pdc->Demodulator, ucSlaveDemod, pdc->fc[ucSlaveDemod].ucDesiredBandWidth, pdc->fc[ucSlaveDemod].ulDesiredFrequency); + //PTI.bSettingFreq = false; + if (dwError) + { + deb_data(" Demod_acquireChannel fail! 0x%08x\n", dwError); + goto exit; + } + else //when success acquireChannel, record currentFreq/currentBW. + { + pdc->fc[ucSlaveDemod].ulCurrentFrequency = pdc->fc[ucSlaveDemod].ulDesiredFrequency; + pdc->fc[ucSlaveDemod].ucCurrentBandWidth = pdc->fc[ucSlaveDemod].ucDesiredBandWidth; + } + } + + if(pdc->StreamType == StreamType_DVBT_DATAGRAM) { + PDC->fc[ucSlaveDemod].OvrFlwChk = 5; + } + + /*if (pdc->fc[ucSlaveDemod].ulDesiredFrequency!=0 && pdc->fc[ucSlaveDemod].ucDesiredBandWidth!=0) + { + // patch for Demodulator_isLocked + //mdelay(700); + + dwError= Demodulator_isLocked((Demodulator*) &pdc->Demodulator, ucSlaveDemod, &bLock); + if(dwError) + deb_data(" Demodulator_isLocked is failed!\n"); + else + { + deb_data(" The signal is %s Lock\n", bLock?"":"not"); + + //patch for mce channel change lag + if(bLock) { + mdelay(500); + } + } + }*/ + + PTI.bTunerOK = true; + +exit: + + PTI.bSettingFreq = false; + + return(dwError); +} + +DWORD DRV_ResetPID( + IN void* handle, + IN BYTE chip +) +{ + deb_data("- Enter %s Function -\n ",__FUNCTION__); + + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + //Clear pidTable + dwError = Demodulator_resetPid ((Demodulator*) &pdc->Demodulator, chip); + + return(dwError); + +} + +DWORD DRV_AddPID( + IN void* handle, + IN BYTE ucSlaveDemod, + IN Byte index, + IN Pid pid +) +{ + deb_data("- Enter %s Function - , index:%d, pid:%x \n",__FUNCTION__, index, pid.value); + + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + dwError = Demodulator_addPidToFilter ((Demodulator*) &pdc->Demodulator, ucSlaveDemod,index, pid); + + return(dwError); + +} + +DWORD DRV_RemovePID( + IN void* handle, + IN BYTE ucSlaveDemod, + IN Byte index, + IN Pid pid +) +{ + deb_data("- Enter %s Function - , index:%d, pid:%x \n",__FUNCTION__, index, pid.value); + + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + dwError = Demodulator_removePidAt ((Demodulator*) &pdc->Demodulator, ucSlaveDemod,index, pid); + + return(dwError); + +} + +DWORD DRV_PIDOnOff( + IN void * handle, + IN BYTE ucSlaveDemod, + IN bool bOn +) +{ + deb_data("- Enter %s Function -onoff:%d\n ",__FUNCTION__, bOn); + + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + if (bOn) + dwError = Demodulator_controlPidFilter ((Demodulator*) &pdc->Demodulator, ucSlaveDemod, 1); + else + dwError = Demodulator_controlPidFilter ((Demodulator*) &pdc->Demodulator, ucSlaveDemod, 0); + + return(dwError); +} + +static DWORD DRV_isLocked( + void* handle, + BYTE ucSlaveDemod, + Bool* bLock +) +{ + DWORD dwError = Error_NO_ERROR; + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + *bLock = true; + + deb_data("- Enter %s Function -\n ",__FUNCTION__); + + dwError= Demodulator_isLocked((Demodulator*) &pdc->Demodulator, ucSlaveDemod, bLock); + if(dwError) + deb_data(" Demodulator_isLocked is failed!\n"); + else + deb_data(" The chip=%d signal is %s Lock\n", ucSlaveDemod, *bLock?"":"not"); + + return(dwError); +} +static DWORD DRV_getSignalStrength( + void* handle, + BYTE ucSlaveDemod, + BYTE* strength +) +{ + DWORD dwError = Error_NO_ERROR; + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + deb_data("- Enter %s Function -\n ",__FUNCTION__); + + dwError= Demodulator_getSignalStrength((Demodulator*) &pdc->Demodulator, ucSlaveDemod, strength); + if(dwError) + deb_data(" Demodulator_getSignalStrength is failed!\n"); + else + deb_data(" The signal strength is %d \n", *strength); + + return(dwError); +} + +static DWORD DRV_getSignalStrengthDbm( + void* handle, + BYTE ucSlaveDemod, + Long* strengthDbm +) +{ + DWORD dwError = Error_NO_ERROR; + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + deb_data("- Enter %s Function -\n ",__FUNCTION__); + + dwError= Demodulator_getSignalStrengthDbm((Demodulator*) &pdc->Demodulator, ucSlaveDemod, 1, 1, strengthDbm); + if(dwError) + deb_data(" Demodulator_getSignalStrengthDbm is failed!\n"); + else + deb_data(" The signal strengthDbm is %d \n", *strengthDbm); + + return(dwError); +} + +static DWORD DRV_getChannelStatistic( + void* handle, + BYTE ucSlaveDemod, + ChannelStatistic* channelStatistic +) +{ + DWORD dwError = Error_NO_ERROR; + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + deb_data("- Enter %s Function -\n ",__FUNCTION__); + + dwError= Demodulator_getChannelStatistic((Demodulator*) &pdc->Demodulator, ucSlaveDemod, channelStatistic); + if(dwError) + deb_data(" Demodulator_getChannelStatistic is failed!\n"); + + return(dwError); +} + +static DWORD DRV_getChannelModulation( + void* handle, + BYTE ucSlaveDemod, + ChannelModulation* channelModulation +) +{ + DWORD dwError = Error_NO_ERROR; + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + deb_data("- Enter %s Function -\n ",__FUNCTION__); + + dwError= Standard_getChannelModulation((Demodulator*) &pdc->Demodulator, ucSlaveDemod, channelModulation); + if(dwError) + deb_data(" Demodulator_getChannelStatistic is failed!\n"); + + return(dwError); +} + +static DWORD DRV_getSNRValue( + void* handle, + DWORD* snr_value +) +{ + DWORD dwError = Error_NO_ERROR; + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + BYTE snr_reg_23_16, snr_reg_15_8, snr_reg_7_0; + + deb_data("- Enter %s Function -\n ",__FUNCTION__); + + + dwError = Demodulator_readRegister((Demodulator*) &pdc->Demodulator, 0,Processor_OFDM, 0x2e,(unsigned char *) &snr_reg_23_16); + if(dwError) + deb_data(" Demodulator_getSNR snr_reg_23_16 is failed!\n"); + + dwError = Demodulator_readRegister((Demodulator*) &pdc->Demodulator, 0,Processor_OFDM, 0x2d,(unsigned char *) &snr_reg_15_8); + if(dwError) + deb_data(" Demodulator_getSNR snr_reg_15_8 is failed!\n"); + + dwError = Demodulator_readRegister((Demodulator*) &pdc->Demodulator, 0,Processor_OFDM, 0x2c,(unsigned char *) &snr_reg_7_0); + if(dwError) + deb_data(" Demodulator_getSNR snr_reg_7_0 is failed!\n"); + + *snr_value = (snr_reg_23_16&0xff)*256*256+(snr_reg_15_8&0xff)*256+(snr_reg_7_0&0xff); + + return(dwError); +} + +static DWORD DRV_getFirmwareVersionFromFile( + Processor processor, + DWORD* version +) +{ + DWORD OFDM_VER1 = DVB_OFDM_VERSION1; + DWORD OFDM_VER2 = DVB_OFDM_VERSION2; + DWORD OFDM_VER3 = DVB_OFDM_VERSION3; + DWORD OFDM_VER4 = DVB_OFDM_VERSION4; + + DWORD LINK_VER1 = DVB_LL_VERSION1; + DWORD LINK_VER2 = DVB_LL_VERSION2; + DWORD LINK_VER3 = DVB_LL_VERSION3; + DWORD LINK_VER4 = DVB_LL_VERSION4; + + if(processor == Processor_OFDM) { + *version = (DWORD)( (OFDM_VER1 << 24) + (OFDM_VER2 << 16) + (OFDM_VER3 << 8) + OFDM_VER4); + } + else { //LINK + *version = (DWORD)( (LINK_VER1 << 24) + (LINK_VER2 << 16) + (LINK_VER3 << 8) + LINK_VER4); + } + + return *version; +} + +static DWORD DRV_Initialize( + void * handle +) +{ + DWORD error = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + DWORD fileVersion, cmdVersion = 0; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + if(pdc->Demodulator.booted) //from Standard_setBusTuner() > Standard_getFirmwareVersion() + { + //use "#define version" to get fw version (from firmware.h title) + error = DRV_getFirmwareVersionFromFile(Processor_OFDM, &fileVersion); + + //use "Command_QUERYINFO" to get fw version + error = Demodulator_getFirmwareVersion((Demodulator*) &pdc->Demodulator, Processor_OFDM, &cmdVersion); + if(error) deb_data("DRV_Initialize : Demodulator_getFirmwareVersion : error = 0x%08x\n", error); + + if(cmdVersion != fileVersion) + { + deb_data("Reboot: Outside Fw = 0x%X, Inside Fw = 0x%X", fileVersion, cmdVersion); + error = Demodulator_reboot((Demodulator*) &pdc->Demodulator); + pdc->bBootCode = true; + if(error) + { + deb_data("Demodulator_reboot : error = 0x%08x\n", error); + return error; + } + else { + return Error_NOT_READY; + } + } + else + { + deb_data(" Fw version is the same!\n"); + error = Error_NO_ERROR; + } + }//pdc->Demodulator.booted + +ReInit: //Patch for NIM fail or disappear, Maggie + error = Demodulator_initialize ((Demodulator*) &pdc->Demodulator, pdc->Demodulator.chipNumber , 8000, pdc->StreamType, pdc->architecture); + if (error) + { + deb_data("Device initialize fail : 0x%08x\n", error); + if( ((error&Error_FIRMWARE_STATUS) && (error&0x10)) && (pdc->Demodulator.chipNumber>1) ) + { + pdc->Demodulator.cmdDescription->sendCommand ((Demodulator*) &pdc->Demodulator, Command_FW_DOWNLOAD_END, 0, Processor_LINK, 0, NULL, 0, NULL); + + deb_data(" Retry to download FW with Single TS\n"); + pdc->Demodulator.chipNumber = 1; + pdc->bDualTs = false; + error = Demodulator_writeRegister ((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, 0x417F, 0); + goto ReInit; + } + } + else { + deb_data(" Device initialize Ok!!\n"); + } + + Demodulator_getFirmwareVersion ((Demodulator*) &pdc->Demodulator, Processor_OFDM, &cmdVersion); + deb_data(" FwVer OFDM = 0x%X, ", cmdVersion); + Demodulator_getFirmwareVersion ((Demodulator*) &pdc->Demodulator, Processor_LINK, &cmdVersion); + deb_data("FwVer LINK = 0x%X\n", cmdVersion); + + return error; + +} + +static DWORD DRV_InitDevInfo( + void * handle, + BYTE ucSlaveDemod +) +{ + DWORD dwError = Error_NO_ERROR; + + PDC->fc[ucSlaveDemod].ulCurrentFrequency = 0; + PDC->fc[ucSlaveDemod].ucCurrentBandWidth = 0; + + PDC->fc[ucSlaveDemod].ulDesiredFrequency = 0; + PDC->fc[ucSlaveDemod].ucDesiredBandWidth = 6000; + + //For PID Filter Setting + //PDC->fc[ucSlaveDemod].ulcPIDs = 0; + PDC->fc[ucSlaveDemod].bEnPID = false; + + PDC->fc[ucSlaveDemod].bApOn = false; + + PDC->fc[ucSlaveDemod].bResetTs = false; + + + + PTI.bTunerOK = false; + PTI.bSettingFreq = false; + + return dwError; +} + +static DWORD DRV_GetEEPROMConfig( + void * handle) +{ + DWORD dwError = Error_NO_ERROR; + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + BYTE ucSlaveDemod = 0; + BYTE btmp = 0; + int cnt; + + deb_data("- Enter %s Function -",__FUNCTION__); + + //bIrTblDownload option + dwError = Demodulator_readRegisters((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, EEPROM_IRMODE, 1, &btmp); + if (dwError) return(dwError); + PDC->bIrTblDownload = btmp ? true:false; + deb_data( "EEPROM_IRMODE = 0x%02X, ", btmp); + deb_data("bIrTblDownload %s\n", PDC->bIrTblDownload?"ON":"OFF"); + + PDC->bDualTs = false; + PDC->architecture = Architecture_DCA; + PDC->Demodulator.chipNumber = 1; + PDC->bDCAPIP = false; + + //bDualTs option + dwError = Demodulator_readRegisters((Demodulator*) &pdc->Demodulator, 0, Processor_LINK,EEPROM_TSMODE, 1, &btmp); + if (dwError) return(dwError); + deb_data("EEPROM_TSMODE = 0x%02X", btmp); + + if (btmp == 0) + deb_data("TSMode = TS1 mode\n"); + else if (btmp == 1) + { + deb_data("TSMode = DCA+PIP mode\n"); + PDC->architecture = Architecture_DCA; + PDC->Demodulator.chipNumber = 2; + PDC->bDualTs = true; + //PDC->bDCAPIP = true; + } + else if (btmp == 3) + { + deb_data("TSMode = PIP mode\n"); + PDC->architecture = Architecture_PIP; + PDC->Demodulator.chipNumber = 2; + PDC->bDualTs = true; + } + else + { + deb_data("TSMode = DCA mode\n"); + PDC->architecture = Architecture_DCA; + PDC->Demodulator.chipNumber = 2; + } + + if(PDC->bDualTs) { + cnt = 2; + } + else { + cnt = 1; + } + + for(ucSlaveDemod; ucSlaveDemod < cnt; ucSlaveDemod++) + { + dwError = DRV_GetEEPROMConfig2(pdc, ucSlaveDemod); + if (dwError) return(dwError); + dwError = DRV_InitDevInfo(pdc, ucSlaveDemod); + if (dwError) return(dwError); + } + + return(dwError); +} + +static DWORD DRV_SetBusTuner( + void * handle, + Word busId, + Word tunerId +) +{ + DWORD dwError = Error_NO_ERROR; + DWORD version = 0; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + deb_data("- Enter %s Function -",__FUNCTION__); + deb_data("busId = 0x%x, tunerId =0x%x\n", busId, tunerId); + + if ((pdc->UsbMode==0x0110) && (busId==Bus_USB)) { + busId=Bus_USB11; + } + + dwError = Demodulator_setBusTuner ((Demodulator*) &pdc->Demodulator, busId, tunerId); + if (dwError) {deb_data("Demodulator_setBusTuner error\n");return dwError;} + + dwError = Demodulator_getFirmwareVersion ((Demodulator*) &pdc->Demodulator, Processor_LINK, &version); + if (version != 0) { + pdc->Demodulator.booted = True; + } + else { + pdc->Demodulator.booted = False; + } + if (dwError) {deb_data("Demodulator_getFirmwareVersion error\n");} + + return(dwError); +} + + + +static DWORD DRV_TunerPowerCtrl( + void * handle, + BYTE ucSlaveDemod, + Bool bPowerOn +) +{ + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + deb_data("- Enter %s Function -",__FUNCTION__); + deb_data("chip = %d\n", ucSlaveDemod); + + /* init gpioH7 */ + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh7_en, reg_top_gpioh7_en_pos, reg_top_gpioh7_en_len, 1); + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh7_on, reg_top_gpioh7_on_pos, reg_top_gpioh7_on_len, 1); + + if(bPowerOn) + PTI.bTunerInited = true; + else + PTI.bTunerInited = false; + + + if(bPowerOn) //tuner on + { + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh7_o, reg_top_gpioh7_o_pos, reg_top_gpioh7_o_len, 1); + + if(pdc->bTunerPowerOff == true) + { + dwError = Demodulator_initialize ((Demodulator*) &pdc->Demodulator, pdc->Demodulator.chipNumber , pdc->Demodulator.bandwidth[0], pdc->StreamType, pdc->architecture); + pdc->bTunerPowerOff = false; + } + } + else //tuner off + { + if(pdc->architecture == Architecture_PIP) + { + if(pdc->fc[0].tunerinfo.bTunerInited == false && pdc->fc[1].tunerinfo.bTunerInited == false) + { + if(pdc->bTunerPowerOff == false) + { + dwError = Demodulator_finalize((Demodulator*) &pdc->Demodulator); + pdc->bTunerPowerOff = true; + } + + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh7_o, reg_top_gpioh7_o_pos, reg_top_gpioh7_o_len, 0); + } + } + else + { + if(pdc->bTunerPowerOff == false) + { + dwError = Demodulator_finalize((Demodulator*) &pdc->Demodulator); + pdc->bTunerPowerOff = true; + } + + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh7_o, reg_top_gpioh7_o_pos, reg_top_gpioh7_o_len, 0); + } + + } + return(dwError); +} + +static DWORD DRV_ApCtrl ( + void * handle, + Byte ucSlaveDemod, + Bool bOn +) +{ + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + deb_data(" ucSlaveDemod = %d, bOn = %s \n", ucSlaveDemod, bOn?"ON":"OFF"); + + //deb_data("enter DRV_ApCtrl: Demod[%d].GraphBuilt = %d", ucSlaveDemod, pdc->fc[ucSlaveDemod].GraphBuilt); + + dwError = DRV_TunerPowerCtrl(pdc, ucSlaveDemod, bOn); + if(dwError) { deb_data(" DRV_TunerPowerCtrl Fail: 0x%08x\n", dwError); return(dwError);} + + + dwError = Demodulator_controlPowerSaving((Demodulator*) &pdc->Demodulator, ucSlaveDemod, bOn); + if(dwError) { deb_data(" DRV_ApCtrl: Demodulator_controlPowerSaving error = 0x%08x\n", dwError); return(dwError);} + + return(dwError); +} + + +static DWORD DRV_TunerWakeup( + void * handle +) +{ + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT) handle; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + //tuner power on + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh7_o, reg_top_gpioh7_o_pos, reg_top_gpioh7_o_len, 1); + + return(dwError); + +} + +static DWORD DRV_Reboot( + void * handle +) +{ + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT) handle; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + dwError = Demodulator_reboot((Demodulator*) &pdc->Demodulator); + + return(dwError); +} + + + +static DWORD DRV_USBSetup( + void* handle +) +{ + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT) handle; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + int i; + + if (pdc->Demodulator.chipNumber == 2) + { + //timing + for (i=0; i<2; i++) + { + dwError = Demodulator_writeRegisterBits ((Demodulator*) &pdc->Demodulator,i, Processor_OFDM, p_reg_dca_fpga_latch, reg_dca_fpga_latch_pos, reg_dca_fpga_latch_len, 0x66); + if(dwError) return (dwError); + dwError = Demodulator_writeRegisterBits ((Demodulator*) &pdc->Demodulator, i, Processor_OFDM, p_reg_dca_platch, reg_dca_platch_pos, reg_dca_platch_len, 1); + if(dwError) return (dwError); + } + } + return(dwError); +} + +static DWORD DRV_NIMSuspend( + void * handle, + bool bSuspend + +) +{ + deb_data("- Enter DRV_NIMSuspend : bSuspend = %s\n", bSuspend ? "ON":"OFF"); + + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT) handle; + + if(bSuspend) //sleep + { + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh5_o, reg_top_gpioh5_o_pos, reg_top_gpioh5_o_len, 1); + if(dwError) return (dwError); + } + else //resume + { + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh5_o, reg_top_gpioh5_o_pos, reg_top_gpioh5_o_len, 0); + if(dwError) return (dwError); + } + + return(dwError); +} + +static DWORD DRV_InitNIMSuspendRegs( + void * handle +) +{ + deb_data("- Enter %s Function -\n",__FUNCTION__); + + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT) handle; + + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh5_en, reg_top_gpioh5_en_pos, reg_top_gpioh5_en_len, 1); + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh5_on, reg_top_gpioh5_on_pos, reg_top_gpioh5_on_len, 1); + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh5_o, reg_top_gpioh5_o_pos, reg_top_gpioh5_o_len, 0); + + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 1, Processor_LINK, p_reg_top_pwrdw, reg_top_pwrdw_pos, reg_top_pwrdw_len, 1); + + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 1, Processor_LINK, p_reg_top_pwrdw_hwen, reg_top_pwrdw_hwen_pos, reg_top_pwrdw_hwen_len, 1); + + return(dwError); +} + +static DWORD DRV_NIMReset( + void * handle +) +{ + deb_data("- Enter %s Function -\n",__FUNCTION__); + + DWORD dwError = Error_NO_ERROR; + + PDEVICE_CONTEXT pdc = (PDEVICE_CONTEXT)handle; + + //Set AF0350 GPIOH1 to 0 to reset AF0351 + + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh1_en, reg_top_gpioh1_en_pos, reg_top_gpioh1_en_len, 1); + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh1_on, reg_top_gpioh1_on_pos, reg_top_gpioh1_on_len, 1); + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh1_o, reg_top_gpioh1_o_pos, reg_top_gpioh1_o_len, 0); + + mdelay(50); + + dwError = Demodulator_writeRegisterBits((Demodulator*) &pdc->Demodulator, 0, Processor_LINK, p_reg_top_gpioh1_o, reg_top_gpioh1_o_pos, reg_top_gpioh1_o_len, 1); + + return(dwError); +} + +//************** DL_ *************// + +static DWORD DL_NIMReset( + void * handle +) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + dwError = DRV_NIMReset(handle); + + mutex_unlock(&mymutex); + + return (dwError); +} + +static DWORD DL_USBSetup( + void * handle +) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + dwError = DRV_USBSetup(handle); + + mutex_unlock(&mymutex); + + return (dwError); +} + +static DWORD DL_NIMSuspend( + void * handle, + bool bSuspend +) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + dwError = DRV_NIMSuspend(handle, bSuspend); + + mutex_unlock(&mymutex); + + return (dwError); +} + +static DWORD DL_InitNIMSuspendRegs( + void * handle +) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + dwError = DRV_InitNIMSuspendRegs(handle); + + mutex_unlock(&mymutex); + + return (dwError); +} +static DWORD DL_Initialize( + void * handle +) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + dwError = DRV_Initialize(handle); + + mutex_unlock(&mymutex); + + return (dwError); + +} + +static DWORD DL_SetBusTuner( + void * handle, + Word busId, + Word tunerId +) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + dwError = DRV_SetBusTuner(handle, busId, tunerId); + + mutex_unlock(&mymutex); + + return (dwError); + +} + +static DWORD DL_GetEEPROMConfig( + void * handle +) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + dwError = DRV_GetEEPROMConfig(handle); + + mutex_unlock(&mymutex); + + return(dwError); +} + +static DWORD DL_TunerWakeup( + void * handle +) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + dwError = DRV_TunerWakeup(handle); + + mutex_unlock(&mymutex); + + return(dwError); +} +static DWORD DL_IrTblDownload( + void * handle +) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + dwError = DRV_IrTblDownload(handle); + + mutex_unlock(&mymutex); + + return(dwError); +} + + +DWORD DL_TunerPowerCtrl(u8 bPowerOn) +{ + + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + BYTE ucSlaveDemod=0; + + deb_data("enter DL_TunerPowerCtrl: bOn = %s\n", bPowerOn?"ON":"OFF"); + + for (ucSlaveDemod=0; ucSlaveDemod<PDC->Demodulator.chipNumber; ucSlaveDemod++) + { + dwError = DRV_TunerPowerCtrl(PDC, ucSlaveDemod, bPowerOn); + if(dwError) deb_data(" DRV_TunerPowerCtrl Fail: 0x%08x\n", dwError); + } + + mutex_unlock(&mymutex); + + return (dwError); +} +//EXPORT_SYMBOL(DL_TunerPowerCtrl); + +DWORD DL_ResetPID( + IN BYTE chip +) +{ + mutex_lock(&mymutex); + + DWORD dwError = DRV_ResetPID(PDC, chip); + + mutex_unlock(&mymutex); + + return(dwError); +} + +DWORD DL_AddPID( + IN BYTE ucSlaveDemod, + IN Byte index, + IN Pid pid +) +{ + mutex_lock(&mymutex); + + DWORD dwError = DRV_AddPID(PDC, ucSlaveDemod,index, pid); + + mutex_unlock(&mymutex); + + return(dwError); +} + +DWORD DL_RemovePID( + IN BYTE ucSlaveDemod, + IN Byte index, + IN Pid pid +) +{ + mutex_lock(&mymutex); + + DWORD dwError = DRV_RemovePID(PDC, ucSlaveDemod,index, pid); + + mutex_unlock(&mymutex); + + return(dwError); +} + +DWORD DL_PIDOnOff( + IN BYTE ucSlaveDemod, + IN bool bOn +) +{ + mutex_lock(&mymutex); + + DWORD dwError = DRV_PIDOnOff(PDC, ucSlaveDemod, bOn); + + mutex_unlock(&mymutex); + + return(dwError); +} + +DWORD DL_ApCtrl ( + BYTE ucSlaveDemod, + Bool bOn +) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + BYTE i=0; + + deb_data("- Enter %s Function -",__FUNCTION__); + deb_data(" chip = %d bOn = %s\n", ucSlaveDemod, bOn?"ON":"OFF"); + + if(PDC->architecture != Architecture_PIP) + { + if ( PDC->Demodulator.chipNumber == 2 && bOn) dwError = DL_NIMSuspend(PDC, false); + + for (i=0; i<PDC->Demodulator.chipNumber; i++) + { + if (bOn) + dwError = DRV_ApCtrl (PDC, i, bOn); + else + if (PDC->bTunerPowerOff != true) dwError = DRV_ApCtrl (PDC, i, bOn); + + if(!bOn) + { + PDC->fc[i].ulDesiredFrequency = 0; + PDC->fc[i].ucDesiredBandWidth = 0; + } + } + + if(PDC->Demodulator.chipNumber == 2 && !bOn) dwError = DL_NIMSuspend(PDC, true); + } + else + { + if (bOn) + { + PDC->fc[ucSlaveDemod].GraphBuilt = 1; + + if (PDC->fc[0].GraphBuilt == 0 || PDC->fc[1].GraphBuilt == 0) + dwError = DL_NIMSuspend(PDC, false); + + dwError = DRV_ApCtrl (PDC, ucSlaveDemod, bOn); + } + else + { + + PDC->fc[ucSlaveDemod].GraphBuilt = 0; + + if (PDC->bTunerPowerOff != true) dwError = DRV_ApCtrl (PDC, ucSlaveDemod, bOn); + + if (PDC->fc[0].GraphBuilt == 0 && PDC->fc[1].GraphBuilt == 0 && PDC->bTunerPowerOff == true) + dwError = DL_NIMSuspend(PDC, true); + } + } + + mutex_unlock(&mymutex); + + return(dwError); +} +//EXPORT_SYMBOL(DL_ApCtrl); + +DWORD DL_Tuner_SetFreqBw(BYTE ucSlaveDemod, u32 dwFreq,u8 ucBw) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + if (PDC->fc[ucSlaveDemod].ulDesiredFrequency!=dwFreq || PDC->fc[ucSlaveDemod].ucDesiredBandWidth!=ucBw*1000) + dwError = DRV_SetFreqBw(PDC, ucSlaveDemod, dwFreq, ucBw); + + mutex_unlock(&mymutex); + return(dwError); +} +//EXPORT_SYMBOL(DL_Tuner_SetFreq); + +DWORD DL_isLocked(BYTE ucSlaveDemod, Bool *bLock ) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + dwError = DRV_isLocked(PDC, ucSlaveDemod, bLock); + + mutex_unlock(&mymutex); + return(dwError); +} + +DWORD DL_getSignalStrength(BYTE ucSlaveDemod, BYTE* strength) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + dwError = DRV_getSignalStrength(PDC, ucSlaveDemod, strength); + +// deb_data(" The signal strength is %d \n", *strength); + mutex_unlock(&mymutex); + + return(dwError); +} + +DWORD DL_getSignalStrengthDbm(BYTE ucSlaveDemod, Long* strengthDbm) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + dwError = DRV_getSignalStrengthDbm(PDC, ucSlaveDemod, strengthDbm); + +mutex_unlock(&mymutex); + return(dwError); +} + +DWORD DL_getChannelStatistic(BYTE ucSlaveDemod, ChannelStatistic* channelStatistic) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + dwError = DRV_getChannelStatistic(PDC, ucSlaveDemod, channelStatistic); + + mutex_unlock(&mymutex); + + return(dwError); +} + +DWORD DL_getChannelModulation(BYTE ucSlaveDemod, ChannelModulation* channelModulation) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + dwError = DRV_getChannelModulation(PDC, ucSlaveDemod, channelModulation); + + mutex_unlock(&mymutex); + + return(dwError); +} + +DWORD DL_getSNR(BYTE ucSlaveDemod, Constellation* constellation, BYTE* snr) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + ChannelModulation channelModulation; + DWORD snr_value; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + dwError = DRV_getChannelModulation(PDC, ucSlaveDemod, &channelModulation); + if (dwError) return(dwError); + + dwError = DRV_getSNRValue(PDC, &snr_value); + if (dwError) return(dwError); + + *constellation = channelModulation.constellation; + + if(channelModulation.constellation == 0) //Constellation_QPSK + { + if(snr_value < 0xB4771) *snr = 0; + else if(snr_value < 0xC1AED) *snr = 1; + else if(snr_value < 0xD0D27) *snr = 2; + else if(snr_value < 0xE4D19) *snr = 3; + else if(snr_value < 0xE5DA8) *snr = 4; + else if(snr_value < 0x107097) *snr = 5; + else if(snr_value < 0x116975) *snr = 6; + else if(snr_value < 0x1252D9) *snr = 7; + else if(snr_value < 0x131FA4) *snr = 8; + else if(snr_value < 0x13D5E1) *snr = 9; + else if(snr_value < 0x148E53) *snr = 10; + else if(snr_value < 0x15358B) *snr = 11; + else if(snr_value < 0x15DD29) *snr = 12; + else if(snr_value < 0x168112) *snr = 13; + else if(snr_value < 0x170B61) *snr = 14; + else if(snr_value < 0x17A532) *snr = 15; + else if(snr_value < 0x180F94) *snr = 16; + else if(snr_value < 0x186ED2) *snr = 17; + else if(snr_value < 0x18B271) *snr = 18; + else if(snr_value < 0x18E118) *snr = 19; + else if(snr_value < 0x18FF4B) *snr = 20; + else if(snr_value < 0x190AF1) *snr = 21; + else if(snr_value < 0x191451) *snr = 22; + else *snr = 23; + } + + else if ( channelModulation.constellation == 1) //Constellation_16QAM + { + if(snr_value < 0x4F0D5) *snr = 0; + else if(snr_value < 0x5387A) *snr = 1; + else if(snr_value < 0x573A4) *snr = 2; + else if(snr_value < 0x5A99E) *snr = 3; + else if(snr_value < 0x5CC80) *snr = 4; + else if(snr_value < 0x5EB62) *snr = 5; + else if(snr_value < 0x5FECF) *snr = 6; + else if(snr_value < 0x60B80) *snr = 7; + else if(snr_value < 0x62501) *snr = 8; + else if(snr_value < 0x64865) *snr = 9; + else if(snr_value < 0x69604) *snr = 10; + else if(snr_value < 0x6F356) *snr = 11; + else if(snr_value < 0x7706A) *snr = 12; + else if(snr_value < 0x804D3) *snr = 13; + else if(snr_value < 0x89D1A) *snr = 14; + else if(snr_value < 0x93E3D) *snr = 15; + else if(snr_value < 0x9E35D) *snr = 16; + else if(snr_value < 0xA7C3C) *snr = 17; + else if(snr_value < 0xAFAF8) *snr = 18; + else if(snr_value < 0xB719D) *snr = 19; + else if(snr_value < 0xBDA6A) *snr = 20; + else if(snr_value < 0xC0C75) *snr = 21; + else if(snr_value < 0xC3F7D) *snr = 22; + else if(snr_value < 0xC5E62) *snr = 23; + else if(snr_value < 0xC6C31) *snr = 24; + else if(snr_value < 0xC7925) *snr = 25; + else *snr = 26; + } + + else if ( channelModulation.constellation == 2) //Constellation_64QAM + { + if(snr_value < 0x256D0) *snr = 0; + else if(snr_value < 0x27A65) *snr = 1; + else if(snr_value < 0x29873) *snr = 2; + else if(snr_value < 0x2B7FE) *snr = 3; + else if(snr_value < 0x2CF1E) *snr = 4; + else if(snr_value < 0x2E234) *snr = 5; + else if(snr_value < 0x2F409) *snr = 6; + else if(snr_value < 0x30046) *snr = 7; + else if(snr_value < 0x30844) *snr = 8; + else if(snr_value < 0x30A02) *snr = 9; + else if(snr_value < 0x30CDE) *snr = 10; + else if(snr_value < 0x31031) *snr = 11; + else if(snr_value < 0x3144C) *snr = 12; + else if(snr_value < 0x315DD) *snr = 13; + else if(snr_value < 0x31920) *snr = 14; + else if(snr_value < 0x322D0) *snr = 15; + else if(snr_value < 0x339FC) *snr = 16; + else if(snr_value < 0x364A1) *snr = 17; + else if(snr_value < 0x38BCC) *snr = 18; + else if(snr_value < 0x3C7D3) *snr = 19; + else if(snr_value < 0x408CC) *snr = 20; + else if(snr_value < 0x43BED) *snr = 21; + else if(snr_value < 0x48061) *snr = 22; + else if(snr_value < 0x4BE95) *snr = 23; + else if(snr_value < 0x4FA7D) *snr = 24; + else if(snr_value < 0x52405) *snr = 25; + else if(snr_value < 0x5570D) *snr = 26; + else if(snr_value < 0x59FEB) *snr = 27; + else if(snr_value < 0x5BF38) *snr = 28; + else *snr = 29; + } + + else + deb_data(" Get constellation is failed!\n"); + + mutex_unlock(&mymutex); + + return(dwError); +} + +DWORD DL_ReSetInterval(void) +{ + + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + mutex_unlock(&mymutex); + + return(dwError); +} +//EXPORT_SYMBOL(DL_ReSetInterval); + +DWORD DL_Reboot(void) +{ + + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + dwError = DRV_Reboot(PDC); + + mutex_unlock(&mymutex); + + return(dwError); +} + +DWORD DL_CheckTunerInited(BYTE ucSlaveDemod, Bool *bOn ) +{ + + mutex_lock(&mymutex); + + DWORD dwError = Error_NO_ERROR; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + + *bOn = PTI.bTunerInited; + + mutex_unlock(&mymutex); + + return(dwError); +} + +DWORD Device_init(struct usb_device *udev,PDEVICE_CONTEXT PDCs, Bool bBoot) +{ + DWORD error = Error_NO_ERROR; + BYTE filterIdx=0; + udevs=udev; + PDC=PDCs; + int errcount=0; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + +// define in Af903x.h +#ifdef QuantaMID + printk(" === AfaDTV on Quanta ===\n"); +#endif +#ifdef EEEPC + printk(" === AfaDTV on EEEPC ===\n"); +#endif + +#ifdef DRIVER_RELEASE_VERSION + printk(" DRIVER_RELEASE_VERSION : %s\n", DRIVER_RELEASE_VERSION); +#else + printk(" DRIVER_RELEASE_VERSION : v0.0-0\n"); +#endif + +#ifdef FW_RELEASE_VERSION + printk(" FW_RELEASE_VERSION : %s\n", FW_RELEASE_VERSION); +#else + printk(" FW_RELEASE_VERSION : v0_0_0_0\n"); +#endif + +#ifdef Version_NUMBER + printk(" API_RELEASE_VERSION : %X.%X.%X\n", Version_NUMBER, Version_DATE, Version_BUILD); +#else + printk(" API_RELEASE_VERSION :000.00000000.0\n"); +#endif + + +// printk(" FW_RELEASE_VERSION : %s\n", FW_RELEASE_VERSION); +// printk(" API_RELEASE_VERSION : %X.%X.%X\n", Version_NUMBER, Version_DATE, Version_BUILD); + + + //************* Set Device init Info *************// + PDC->bEnterSuspend = false; + PDC->bSurpriseRemoval = false; + PDC->bDevNotResp = false; + PDC->bSelectiveSuspend = false; + PDC->bTunerPowerOff = false; + + if (bBoot) + { + PDC->bSupportSelSuspend = false; + PDC->Demodulator.userData = (Handle)PDC; + PDC->Demodulator.chipNumber = 1; + PDC->architecture=Architecture_DCA; + PDC->Demodulator.frequency[0] = 666000; + PDC->Demodulator.bandwidth[0] = 8000; + PDC->bIrTblDownload = false; + PDC->fc[0].tunerinfo.TunerId = 0; + PDC->fc[1].tunerinfo.TunerId = 0; + PDC->bDualTs=false; + PDC->FilterCnt = 0; + PDC->StreamType = StreamType_DVBT_DATAGRAM; + PDC->UsbCtrlTimeOut = 1; + } + else { + PDC->UsbCtrlTimeOut = 5; + }//bBoot + +#ifdef AFA_USB_DEVICE + if (bBoot) { + //************* Set USB Info *************// + PDC->MaxPacketSize = 0x0200; //default USB2.0 + PDC->UsbMode = (PDC->MaxPacketSize == 0x200)?0x0200:0x0110; + deb_data("USB mode= 0x%x\n", PDC->UsbMode); + + PDC->TsPacketCount = (PDC->UsbMode == 0x200)?TS_PACKET_COUNT_HI:TS_PACKET_COUNT_FU; + PDC->TsFrames = (PDC->UsbMode == 0x200)?TS_FRAMES_HI:TS_FRAMES_FU; + PDC->TsFrameSize = TS_PACKET_SIZE*PDC->TsPacketCount; + PDC->TsFrameSizeDw = PDC->TsFrameSize/4; + } + PDC->bEP12Error = false; + PDC->bEP45Error = false; + PDC->ForceWrite = false; + PDC->ulActiveFilter = 0; +#else + PDC->bSupportSuspend = false; +#endif//AFA_USB_DEVICE + +#ifdef AFA_USB_DEVICE + if(bBoot) + { + //patch for eeepc + error = DL_SetBusTuner (PDC, Bus_USB, Tuner_Afatech_AF9007); + PDC->UsbCtrlTimeOut = 5; + + error = DL_SetBusTuner (PDC, Bus_USB, Tuner_Afatech_AF9007); + if (error) + { + deb_data("First DL_SetBusTuner fail : 0x%08x\n",error ); + errcount++; + goto Exit; + } + + error =DL_GetEEPROMConfig(PDC); + if (error) + { + deb_data("DL_GetEEPROMConfig fail : 0x%08x\n", error); + errcount++; + goto Exit; + } + }//bBoot + + error = DL_SetBusTuner(PDC, Bus_USB, PDC->fc[0].tunerinfo.TunerId); + if (error) + { + deb_data("DL_SetBusTuner fail!\n"); + errcount++; + goto Exit; + } + + + if (PDC->Demodulator.chipNumber == 2 && !PDC->Demodulator.booted) //plug/cold-boot/S4 + { + error = DL_NIMReset(PDC); + } + else if(PDC->Demodulator.chipNumber == 2 && PDC->Demodulator.booted) //warm-boot/(S1) + { + error = DL_NIMSuspend(PDC, false); + error = DL_TunerWakeup(PDC); //actually for mt2266 + } + + + if(PDC->Demodulator.chipNumber == 1 && PDC->Demodulator.booted) //warm-boot/(S1) + { + error = DL_TunerWakeup(PDC); + } + if(error) deb_data("DL_NIMReset or DL_NIMSuspend or DL_TunerWakeup fail!\n"); + + error = DL_Initialize(PDC); + if (error) + { + deb_data("DL_Initialize fail! 0x%08x\n", error); + errcount++; + goto Exit; + } + + if (PDC->bIrTblDownload) + { + error = DL_IrTblDownload(PDC); + if (error) {deb_data("DL_IrTblDownload fail");errcount++;} + } + + if (PDC->Demodulator.chipNumber == 2) + { + error = DL_USBSetup(PDC); + if (error) deb_data("DRV_SDIOSetup fail!"); + } + + if (PDC->Demodulator.chipNumber == 2) + { + error = DL_InitNIMSuspendRegs(PDC); + if (error) deb_data("DL_InitNIMSuspendRegs fail!"); + } + + for (filterIdx=0; filterIdx< PDC->Demodulator.chipNumber; filterIdx++) + { + if (bBoot || !PDC->fc[filterIdx].GraphBuilt) + { + error = DRV_ApCtrl(PDC, filterIdx, false); + if (error) {deb_data("%d: DRV_ApCtrl Fail!\n", filterIdx);errcount++;} + } + } + +/* if(PDC->Demodulator.chipNumber == 2) + { + if(PDC->fc[0].GraphBuilt==0 && PDC->fc[1].GraphBuilt==0) + { + error = DL_NIMSuspend(PDC, true); + if(error) deb_data("DL_NIMSuspend fail!"); + } + } +*/ + deb_data(" %s success!! \n",__FUNCTION__); + +Exit: +#endif //AFA_USB_DEVICE + + if(errcount) + printk( "[Device_init] Error %d\n", errcount); + return (error); +} +//EXPORT_SYMBOL(Device_init); + diff --git a/src/af903x-fe.c b/src/af903x-fe.c new file mode 100644 index 0000000..1939671 --- /dev/null +++ b/src/af903x-fe.c @@ -0,0 +1,249 @@ +#include "af903x.h" +#include "dvb_frontend.h" + +struct af903xm_state { + struct dvb_frontend demod; + fe_bandwidth_t current_bandwidth; +}; + +static int af903x_init(struct dvb_frontend *demod) +{ + DWORD error = Error_NO_ERROR; + deb_data("- Enter %s Function - chip=%d\n",__FUNCTION__, demod->dvb->num); + +/* error = DL_ApCtrl(demod->dvb->num,1 ); + if(error){ + printk("af903x_init return error\n"); + return error; + } +*/ + return 0; +} + +static int af903x_sleep(struct dvb_frontend *demod) +{ + DWORD error = Error_NO_ERROR;; + deb_data("- Enter %s Function - chip=%d\n",__FUNCTION__, demod->dvb->num); + + DeviceReboot = false; + + /* error = DL_ApCtrl(demod->dvb->num, 0); + if (error){ + printk("af903x_sleep return error\n"); + return error; + } +*/ + return 0; + +} + +static int af903x_identify(struct af903xm_state *state) +{ + return 0; +} + +static int af903x_get_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + struct af903xm_state *state = fe->demodulator_priv; + deb_data("- Enter %s Function - chip=%d\n",__FUNCTION__, fe->dvb->num); + fep->inversion = INVERSION_AUTO; + fep->u.ofdm.bandwidth = state->current_bandwidth; + return 0; +} + +static int af903x_set_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + struct af903xm_state *state = fe->demodulator_priv; + struct af903x_ofdm_channel ch; + DWORD error = Error_NO_ERROR; + + deb_data("- Enter %s Function - chip=%d\n",__FUNCTION__, fe->dvb->num); + if (fep->u.ofdm.bandwidth == 0) fep->u.ofdm.bandwidth=8; + if (fep->u.ofdm.bandwidth == 1) fep->u.ofdm.bandwidth=7; + if (fep->u.ofdm.bandwidth == 2) fep->u.ofdm.bandwidth=6; + + ch.RF_kHz = fep->frequency / 1000; + ch.Bw = fep->u.ofdm.bandwidth; + + state->current_bandwidth = fep->u.ofdm.bandwidth; + + deb_data("- Enter %s Function - chip=%d RF=%d, BW=%d\n",__FUNCTION__, fe->dvb->num,ch.RF_kHz,ch.Bw); + + if (ch.RF_kHz<177000 || ch.RF_kHz > 8585000) + ch.RF_kHz = 950000; + + error = DL_Tuner_SetFreqBw(fe->dvb->num,ch.RF_kHz,ch.Bw); + if (error) printk("af903x_set_frontend return error\n"); + + return 0; +} + +static int af903x_read_status(struct dvb_frontend *fe, fe_status_t *stat) +{ + //deb_data("- Enter %s Function -chip=%d\n",__FUNCTION__, fe->dvb->num); + struct af903xm_state *state = fe->demodulator_priv; + + DWORD error = Error_NO_ERROR; + Bool bLock; + + *stat = 0; + + error = DL_isLocked(fe->dvb->num, &bLock); + if(error) return 0;//return error; + + if (bLock) + { + // It's seems ok that always return lock to AP + *stat |= FE_HAS_SIGNAL; + *stat |= FE_HAS_CARRIER; + *stat |= FE_HAS_LOCK; + *stat |= FE_HAS_VITERBI; + *stat |= FE_HAS_SYNC; + } + + return 0; +} + +static int af903x_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct af903xm_state *state = fe->demodulator_priv; + + DWORD error = Error_NO_ERROR; + + ChannelStatistic channelStatistic; + + error = DL_getChannelStatistic(fe->dvb->num, &channelStatistic); + if(error) return error; + + deb_data("- af903x_read_ber postVitErrorCount : %d, postVitBitCount :%d -\n",channelStatistic.postVitErrorCount, channelStatistic.postVitBitCount); + + *ber = channelStatistic.postVitErrorCount * (0xFFFFFFFF / channelStatistic.postVitBitCount); + return 0; +} + +static int af903x_read_snr(struct dvb_frontend* fe, u16 *snr) +{ +// (void) fe; +// *snr = 0x0000; + struct af903xm_state *state = fe->demodulator_priv; + + DWORD error = Error_NO_ERROR; + Constellation constellation; + BYTE SignalSnr = 0; + + error = DL_getSNR(fe->dvb->num, &constellation, &SignalSnr); + if(error) return error; + + deb_data("- af903x_read_snr constellation : %d, SignalSnr :%d -\n",constellation,SignalSnr ); + +#ifdef QuantaMID + *snr = (u16)SignalSnr; +#else + if(constellation == 0) + *snr = (u16)SignalSnr * (0xFFFF / 23) ; + else if(constellation == 1) + *snr = (u16)SignalSnr * (0xFFFF / 26) ; + else if(constellation == 2) + *snr = (u16)SignalSnr * (0xFFFF / 29) ; + else + deb_data(" Get constellation is failed!\n"); +#endif + return 0; +} + +static int af903x_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) +{ + (void) fe; + *unc = 0; + return 0; + +} +static int af903x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + struct af903xm_state *state = fe->demodulator_priv; + + DWORD error = Error_NO_ERROR; + BYTE SignalStrength = 0; + Long SignalStrengthdbm; + + deb_data("- Enter %s Function -\n",__FUNCTION__); +#ifdef QuantaMID + error = DL_getSignalStrengthDbm(fe->dvb->num, &SignalStrengthdbm); + if(error) return error; + + deb_data("- af903x_read_signal_strengthDbm is -%d -\n",-SignalStrengthdbm); + *strength = (u16)(-SignalStrengthdbm); +#else + error = DL_getSignalStrength(fe->dvb->num, &SignalStrength); + if(error) return error; + + deb_data("- af903x_read_signal_strength is %d -\n",SignalStrength); + *strength = (u16)SignalStrength* (0xFFFF/100); +#endif + return 0; +} + +static void af903x_release(struct dvb_frontend *demod) +{ + struct af903xm_state *st = demod->demodulator_priv; + deb_data("- Enter %s Function -\n",__FUNCTION__); + kfree(st); +} + +static struct dvb_frontend_ops af903x_ops; +struct dvb_frontend * af903x_attach(u8 tmp) +{ + struct dvb_frontend *demod; + struct af903xm_state *st; + + deb_data("- Enter %s Function -\n",__FUNCTION__); + st = kzalloc(sizeof(struct af903xm_state), GFP_KERNEL); + if (st == NULL) + return NULL; + + demod = &st->demod; + demod->demodulator_priv = st; + memcpy(&st->demod.ops, &af903x_ops, sizeof(struct dvb_frontend_ops)); + + af903x_identify(st); + + return demod; +} +EXPORT_SYMBOL(af903x_attach); + +static struct dvb_frontend_ops af903x_ops = { + .info = { + .name = "AF903X USB DVB-T", + .type = FE_OFDM, + .frequency_min = 44250000, + .frequency_max = 867250000, + .frequency_stepsize = 62500, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_RECOVER | + FE_CAN_HIERARCHY_AUTO, + }, + + .release = af903x_release, + + .init = af903x_init, + .sleep = af903x_sleep, + + .set_frontend = af903x_set_frontend, + .get_frontend = af903x_get_frontend, + + .read_status = af903x_read_status, + .read_ber = af903x_read_ber, + .read_signal_strength = af903x_read_signal_strength, + .read_snr = af903x_read_snr, + .read_ucblocks = af903x_read_unc_blocks, +}; +MODULE_AUTHOR("Jimmy Chen <JyunYu.Chen@ite.com.tw>"); +MODULE_DESCRIPTION("Driver for the AF903X demodulator"); +MODULE_LICENSE("GPL"); diff --git a/src/af903x-ioctl.h b/src/af903x-ioctl.h new file mode 100644 index 0000000..14b6df9 --- /dev/null +++ b/src/af903x-ioctl.h @@ -0,0 +1,29 @@ +#ifndef _AF903X_IOCTL_H_ +#define _AF903X_IOCTL_H_ + +#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */ + +/* + * Ioctl definitions + */ + +/* Use 'k' as magic number */ +#define AFA_IOC_MAGIC 'k' +/* Please use a different 8-bit number in your code */ + +//#define AFA_IOCRESETINTERVAL _IO(AFA_IOC_MAGIC, 0) + +/* + * S means "Set" through a ptr, + * T means "Tell" directly with the argument value + * G means "Get": reply by setting through a pointer + * Q means "Query": response is on the return value + * X means "eXchange": switch G and S atomically + * H means "sHift": switch T and Q atomically + */ + + +/* ... more to come */ + +#define AFA_IOC_MAXNR 14 +#endif /* _AF903X-IOCTL_H_ */ diff --git a/src/af903x-tuner.c b/src/af903x-tuner.c new file mode 100644 index 0000000..20b3a2a --- /dev/null +++ b/src/af903x-tuner.c @@ -0,0 +1,92 @@ +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/delay.h> +#include <linux/dvb/frontend.h> + +#include "dvb_frontend.h" +#include "af903x.h" + +#define IF2 36150 // IF2 frequency = 36.150 MHz +#define FREF 16000 // Quartz oscillator 16 MHz + +static int tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +{ + struct tuner_priv *priv=NULL; + DWORD dwError = Error_NO_ERROR; + DWORD freq = params->frequency ;// 1000; // Hz -> kHz + + priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; + + deb_data("%s - freq : %d , bandwidth : %dn",__FUNCTION__, freq,priv->bandwidth); + + dwError =DL_Tuner_SetFreqBw(fe->dvb->num, freq,priv->bandwidth); + if (dwError) deb_data("tuner_set_params Fail !\n"); + + return 0; +} +static int tuner_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct tuner_priv *priv = fe->tuner_priv; + *frequency = priv->frequency; + return 0; +} + +static int tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) +{ + struct tuner_priv *priv = fe->tuner_priv; + *bandwidth = priv->bandwidth; + return 0; +} + +static int tuner_init(struct dvb_frontend *fe) +{ + + return 0; +} + +static int tuner_sleep(struct dvb_frontend *fe) +{ + return 0; +} + +static int tuner_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; +} + +static const struct dvb_tuner_ops tuner_tuner_ops = { + .info = { + .name = "dvb_usb_tuner", + .frequency_min = 48000000, + .frequency_max = 860000000, + .frequency_step = 50000, + }, + + .release = tuner_release, + + .init = tuner_init, + .sleep = tuner_sleep, + + .set_params = tuner_set_params, + .get_frequency = tuner_get_frequency, + .get_bandwidth = tuner_get_bandwidth +}; + +/* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */ +struct dvb_frontend * tuner_attach(struct dvb_frontend *fe) +{ + struct tuner_priv *priv = NULL; + + priv = kzalloc(sizeof(struct tuner_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; + + memcpy(&fe->ops.tuner_ops, &tuner_tuner_ops, sizeof(struct dvb_tuner_ops)); + + fe->tuner_priv = priv; + + return fe; +} +EXPORT_SYMBOL(tuner_attach); diff --git a/src/af903x.h b/src/af903x.h new file mode 100644 index 0000000..4158343 --- /dev/null +++ b/src/af903x.h @@ -0,0 +1,225 @@ + +#ifndef _AF903X_H_ +#define _AF903X_H_ + +#define DVB_USB_LOG_PREFIX "AF903X" +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/kref.h> +#include <linux/smp_lock.h> +#include <linux/usb.h> +#include <asm/uaccess.h> +#include "dvb-usb.h" +#include "af903x-ioctl.h" +#include "demodulator.h" +#include "userdef.h" +#include "firmware.h" +#include "type.h" +#include "Common.h" +#include <linux/version.h> +#include <linux/mutex.h> + + +#define DRIVER_RELEASE_VERSION "v9.08.14.1" +//***************** customization ***************** +//#define QuantaMID 1 +//#define EEEPC 1 +//***************** from compat.h ***************** +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) +typedef int bool; +#define true 1 +#define false 0 +//***************** from dvb-usb.h ***************** +#define dvb_usb_device_properties dvb_usb_properties +#define dvb_usb_adapter dvb_usb_device +#endif +//***************** from device.h *****************// +#define AFA_USB_DEVICE + +#define SLAVE_DEMOD_2WIREADDR 0x3A + +#define TS_PACKET_SIZE 188 +#define TS_PACKET_COUNT_HI 348 +#define TS_PACKET_COUNT_FU 21 + +//***************** from driver.h *****************// +#define TS_FRAMES_HI 16 +#define TS_FRAMES_FU 128 +#define MAX_USB20_IRP_NUM 5 +#define MAX_USB11_IRP_NUM 2 + +//***************** from afdrv.h *****************// +#define GANY_ONLY 0x42F5 +#define EEPROM_FLB_OFS 8 + +#define EEPROM_IRMODE (GANY_ONLY+EEPROM_FLB_OFS+0x10) //00:disabled, 01:HID +#define EEPROM_SELSUSPEND (GANY_ONLY+EEPROM_FLB_OFS+0x28) //Selective Suspend Mode +#define EEPROM_TSMODE (GANY_ONLY+EEPROM_FLB_OFS+0x28+1) //0:one ts, 1:dual ts +#define EEPROM_2WIREADDR (GANY_ONLY+EEPROM_FLB_OFS+0x28+2) //MPEG2 2WireAddr +#define EEPROM_SUSPEND (GANY_ONLY+EEPROM_FLB_OFS+0x28+3) //Suspend Mode +#define EEPROM_IRTYPE (GANY_ONLY+EEPROM_FLB_OFS+0x28+4) //0:NEC, 1:RC6 +#define EEPROM_SAWBW1 (GANY_ONLY+EEPROM_FLB_OFS+0x28+5) +#define EEPROM_XTAL1 (GANY_ONLY+EEPROM_FLB_OFS+0x28+6) //0:28800, 1:20480 +#define EEPROM_SPECINV1 (GANY_ONLY+EEPROM_FLB_OFS+0x28+7) +#define EEPROM_TUNERID (GANY_ONLY+EEPROM_FLB_OFS+0x30+4) // +#define EEPROM_IFFREQL (GANY_ONLY+EEPROM_FLB_OFS+0x30) +#define EEPROM_IFFREQH (GANY_ONLY+EEPROM_FLB_OFS+0x30+1) +#define EEPROM_IF1L (GANY_ONLY+EEPROM_FLB_OFS+0x30+2) +#define EEPROM_IF1H (GANY_ONLY+EEPROM_FLB_OFS+0x30+3) +#define EEPROM_SHIFT (0x10) //EEPROM Addr Shift for slave front end + + +extern int dvb_usb_af903x_debug; +//#define deb_info(args...) dprintk(dvb_usb_af903x_debug,0x01,args) +//#define deb_fw(args...) dprintk(dvb_usb_af903x_debug,0x02,args) +//#define deb_fwdata(args...) dprintk(dvb_usb_af903x_debug,0x04,args) +//#define deb_data(args...) dprintk(dvb_usb_af903x_debug,0x08,args) + + +//#define DEBUG 1 +#ifdef DEBUG +#define deb_data(args...) printk(KERN_NOTICE args) +#else +#define deb_data(args...) +#endif + +//***************** from device.h *****************// +typedef struct _TUNER_INFO { + + Bool bTunerInited; + Bool bSettingFreq; + BYTE TunerId; + Bool bTunerOK; + Tuner_struct MXL5005_Info; + +} TUNER_INFO, *PTUNER_INFO; +typedef struct _FILTER_CONTEXT_HW { + DWORD ulCurrentFrequency; + WORD ucCurrentBandWidth; + DWORD ulDesiredFrequency; + WORD ucDesiredBandWidth; + //ULONG ulBandWidth; + Bool bTimerOn; + // PKSFILTER filter; + Byte GraphBuilt; + TUNER_INFO tunerinfo; + //SIGNAL_STATISTICS ss; + //SIGNAL_RETRAIN sr; + //DWORD gdwOrigFCW; //move from AF901x.cpp [global variable] + //BYTE gucOrigUnplugTh; //move from AF901x.cpp [global variable] + //BYTE gucPreShiftIdx; //move from AF901x.cpp [global variable] + // PKSFILTERFACTORY pFilterFactory; + int bEnPID; + //ULONG ulcPIDs; + // ULONG aulPIDs[32]; + Bool bApOn; + int bResetTs; + Byte OvrFlwChk; +} FILTER_CONTEXT_HW, *PFILTER_CONTEXT_HW; + +typedef struct _DEVICE_CONTEXT { + FILTER_CONTEXT_HW fc[2]; + Byte DeviceNo; + Bool bBootCode; + Bool bEP12Error; + Bool bEP45Error; + //bool bDebugMsg; + //bool bDevExist; + Bool bDualTs; + Bool bIrTblDownload; + Byte BulkOutData[256]; + u32 WriteLength; + Bool bSurpriseRemoval; + Bool bDevNotResp; + Bool bEnterSuspend; + Bool bSupportSuspend; + Bool bSupportSelSuspend; + u16 regIdx; + Byte eepromIdx; + u16 UsbMode; + u16 MaxPacketSize; + u32 MaxIrpSize; + u32 TsFrames; + u32 TsFrameSize; + u32 TsFrameSizeDw; + u32 TsPacketCount; + //BYTE ucDemod2WireAddr; + //USB_IDLE_CALLBACK_INFO cbinfo; // callback info for selective suspend // our selective suspend IRP + + Bool bSelectiveSuspend; + u32 ulActiveFilter; + //BYTE ucSerialNo; + Architecture architecture; + //BYTE Tuner_Id; + StreamType StreamType; + Bool bDCAPIP; + Bool bSwapFilter; + Byte FilterCnt; + Bool bTunerPowerOff; + //PKSPIN PinSave; + Byte UsbCtrlTimeOut; + + Ganymede Demodulator; + + Bool ForceWrite; + +} DEVICE_CONTEXT, *PDEVICE_CONTEXT; + +#define PTI (PDC->fc[ucSlaveDemod].tunerinfo) //TunerInfo pointer + + + +struct af903x_ofdm_channel { + u32 RF_kHz; + u8 Bw; + s16 nfft; + s16 guard; + s16 nqam; + s16 vit_hrch; + s16 vit_select_hp; + s16 vit_alpha; + s16 vit_code_rate_hp; + s16 vit_code_rate_lp; + u8 intlv_native; +}; + +struct tuner_priv { + struct tuner_config *cfg; + struct i2c_adapter *i2c; + + u32 frequency; + u32 bandwidth; + u16 if1_freq; + u8 fmfreq; +}; + +extern struct dvb_frontend * tuner_attach(struct dvb_frontend *fe); +extern struct dvb_frontend * af903x_attach(u8 TMP); +extern struct dvb_usb_device_properties af903x_properties[]; +extern struct usb_device_id af903x_usb_id_table[]; +extern struct usb_device *udevs; +extern PDEVICE_CONTEXT PDC; +extern int af903x_device_count; + +extern DWORD Device_init(struct usb_device *udev,PDEVICE_CONTEXT PDCs, Bool bBoot); +extern DWORD DL_ApCtrl (BYTE ucSlaveDemod, Bool bOn); +extern DWORD DL_Tuner_SetFreqBw(BYTE ucSlaveDemod,u32 ucFreq,u8 ucBw); +extern DWORD DL_isLocked(BYTE ucSlaveDemod, Bool *bLock); +extern DWORD DL_getSignalStrength(BYTE ucSlaveDemod, BYTE* strength); +extern DWORD DL_getSignalStrengthDbm(BYTE ucSlaveDemod, Long* strengthDbm); +extern DWORD DL_getChannelStatistic(BYTE ucSlaveDemod, ChannelStatistic* channelStatistic); +extern DWORD DL_getChannelModulation(BYTE ucSlaveDemod, ChannelModulation* channelModulation); +extern DWORD DL_getSNR(BYTE ucSlaveDemod, Constellation* constellation, BYTE* snr); +extern DWORD DL_ReSetInterval(void); +extern DWORD DL_Reboot(void); +extern DWORD DL_CheckTunerInited(BYTE ucSlaveDemod, Bool *bOn); +extern DWORD DL_PIDOnOff(BYTE ucSlaveDemod, bool bOn); +extern DWORD DL_ResetPID(BYTE chip); +extern DWORD DL_AddPID(BYTE ucSlaveDemod, Byte index,Pid pid); +extern DWORD DL_RemovePID(BYTE ucSlaveDemod, Byte index,Pid pid); +extern bool TunerInited0, TunerInited1, DevicePower, DeviceReboot; +#endif + diff --git a/src/userdef.h b/src/userdef.h new file mode 100644 index 0000000..612ff9d --- /dev/null +++ b/src/userdef.h @@ -0,0 +1,24 @@ +#ifndef _USERDEF_H_ +#define _USERDEF_H_ + + +//typedef unsigned char BYTE; // 1 byte +//typedef unsigned short WORD; // 2 bytes +//typedef unsigned long DWORD; // 4 bytes +typedef int INT; // 4 bytes +//typedef void * HANDLE; + +#define NULL 0 + +#ifdef IN +#undef IN +#endif + +#ifdef OUT +#undef OUT +#endif + +#define IN __in +#define OUT __out + +#endif // _USERDEF_H_ |