15b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#include "pd-common.h" 25b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#include <linux/kernel.h> 35b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#include <linux/usb.h> 45b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#include <linux/dvb/dmx.h> 55b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#include <linux/delay.h> 65a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h> 75b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 85b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#include "vendorcmds.h" 95b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#include <linux/sched.h> 1060063497a95e716c9a689af3be2687d261f115b4Arun Sharma#include <linux/atomic.h> 115b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 125b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb); 135b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 145b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int dvb_bandwidth[][2] = { 152827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehab { TLG_BW_8, 8000000 }, 162827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehab { TLG_BW_7, 7000000 }, 172827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehab { TLG_BW_6, 6000000 } 185b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie}; 195b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int dvb_bandwidth_length = ARRAY_SIZE(dvb_bandwidth); 205b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 215b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb); 225b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int poseidon_check_mode_dvbt(struct poseidon *pd) 235b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 245b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie s32 ret = 0, cmd_status = 0; 255b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 265b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie set_current_state(TASK_INTERRUPTIBLE); 275b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie schedule_timeout(HZ/4); 285b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 295b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE); 305b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret != 0) 315b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 325b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 335b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T); 345b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret) 355b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 365b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 375b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie /* signal source */ 385b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = send_set_req(pd, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &cmd_status); 395b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret|cmd_status) 405b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 415b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 425b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 435b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 445b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 455b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie/* acquire : 465b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie * 1 == open 475b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie * 0 == release 485b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie */ 495b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int poseidon_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) 505b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 515b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct poseidon *pd = fe->demodulator_priv; 525b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb; 535b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie int ret = 0; 545b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 555b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (!pd) 565b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return -ENODEV; 575b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 585b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb = container_of(fe, struct pd_dvb_adapter, dvb_fe); 595b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (acquire) { 605b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_lock(&pd->lock); 615b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (pd->state & POSEIDON_STATE_DISCONNECT) { 625b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = -ENODEV; 635b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto open_out; 645b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 655b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 665b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (pd->state && !(pd->state & POSEIDON_STATE_DVBT)) { 675b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = -EBUSY; 685b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto open_out; 695b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 705b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 715b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie usb_autopm_get_interface(pd->interface); 725b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (0 == pd->state) { 735b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = poseidon_check_mode_dvbt(pd); 745b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret < 0) { 755b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie usb_autopm_put_interface(pd->interface); 765b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto open_out; 775b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 785b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd->state |= POSEIDON_STATE_DVBT; 795b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->bandwidth = 0; 805b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->prev_freq = 0; 815b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 825b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie atomic_inc(&pd_dvb->users); 835b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie kref_get(&pd->kref); 845b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieopen_out: 855b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_unlock(&pd->lock); 865b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } else { 875b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_stop_streaming(pd_dvb); 885b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 895b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (atomic_dec_and_test(&pd_dvb->users)) { 905b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_lock(&pd->lock); 915b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd->state &= ~POSEIDON_STATE_DVBT; 925b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_unlock(&pd->lock); 935b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 945b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie kref_put(&pd->kref, poseidon_delete); 955b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie usb_autopm_put_interface(pd->interface); 965b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 975b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 985b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 995b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1006c9eaa82da53676db830572f5a41aa9ffea133a1Márton Németh#ifdef CONFIG_PM 1015b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic void poseidon_fe_release(struct dvb_frontend *fe) 1025b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 1035b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct poseidon *pd = fe->demodulator_priv; 1045b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1055b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd->pm_suspend = NULL; 1065b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd->pm_resume = NULL; 1075b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 1086c9eaa82da53676db830572f5a41aa9ffea133a1Márton Németh#else 1096c9eaa82da53676db830572f5a41aa9ffea133a1Márton Németh#define poseidon_fe_release NULL 1106c9eaa82da53676db830572f5a41aa9ffea133a1Márton Németh#endif 1115b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1125b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic s32 poseidon_fe_sleep(struct dvb_frontend *fe) 1135b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 1145b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 1155b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 1165b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1175b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie/* 1185b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie * return true if we can satisfy the conditions, else return false. 1195b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie */ 1205b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic bool check_scan_ok(__u32 freq, int bandwidth, 1215b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *adapter) 1225b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 1235b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (bandwidth < 0) 1245b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return false; 1255b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1265b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (adapter->prev_freq == freq 1275b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie && adapter->bandwidth == bandwidth) { 1285b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie long nl = jiffies - adapter->last_jiffies; 1295b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie unsigned int msec ; 1305b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1315b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie msec = jiffies_to_msecs(abs(nl)); 1325b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return msec > 15000 ? true : false; 1335b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 1345b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return true; 1355b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 1365b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1375b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie/* 1385b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie * Check if the firmware delays too long for an invalid frequency. 1395b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie */ 1405b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int fw_delay_overflow(struct pd_dvb_adapter *adapter) 1415b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 1425b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie long nl = jiffies - adapter->last_jiffies; 1435b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie unsigned int msec ; 1445b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1455b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie msec = jiffies_to_msecs(abs(nl)); 1465b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return msec > 800 ? true : false; 1475b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 1485b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1492827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehabstatic int poseidon_set_fe(struct dvb_frontend *fe) 1505b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 1512827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehab struct dtv_frontend_properties *fep = &fe->dtv_property_cache; 1525b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie s32 ret = 0, cmd_status = 0; 1535b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie s32 i, bandwidth = -1; 1545b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct poseidon *pd = fe->demodulator_priv; 1555b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 1565b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1575b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (in_hibernation(pd)) 1585b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return -EBUSY; 1595b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1605b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_lock(&pd->lock); 1615b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie for (i = 0; i < dvb_bandwidth_length; i++) 1622827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehab if (fep->bandwidth_hz == dvb_bandwidth[i][1]) 1635b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie bandwidth = dvb_bandwidth[i][0]; 1645b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1655b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (check_scan_ok(fep->frequency, bandwidth, pd_dvb)) { 1665b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = send_set_req(pd, TUNE_FREQ_SELECT, 1675b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie fep->frequency / 1000, &cmd_status); 1685b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret | cmd_status) { 1695b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie log("error line"); 1705b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto front_out; 1715b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 1725b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1735b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = send_set_req(pd, DVBT_BANDW_SEL, 1745b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie bandwidth, &cmd_status); 1755b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret | cmd_status) { 1765b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie log("error line"); 1775b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto front_out; 1785b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 1795b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1805b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status); 1815b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret | cmd_status) { 1825b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie log("error line"); 1835b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto front_out; 1845b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 1855b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1865b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie /* save the context for future */ 1875b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie memcpy(&pd_dvb->fe_param, fep, sizeof(*fep)); 1885b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->bandwidth = bandwidth; 1895b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->prev_freq = fep->frequency; 1905b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->last_jiffies = jiffies; 1915b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 1925b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiefront_out: 1935b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_unlock(&pd->lock); 1945b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 1955b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 1965b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 1975b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#ifdef CONFIG_PM 1985b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int pm_dvb_suspend(struct poseidon *pd) 1995b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 2005b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 2015b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_stop_streaming(pd_dvb); 2025b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_urb_cleanup(pd_dvb); 2035b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie msleep(500); 2045b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 2055b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 2065b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2075b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int pm_dvb_resume(struct poseidon *pd) 2085b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 2095b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 2105b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2115b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie poseidon_check_mode_dvbt(pd); 2125b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie msleep(300); 2132827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehab poseidon_set_fe(&pd_dvb->dvb_fe); 2145b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2155b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_start_streaming(pd_dvb); 2165b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 2175b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 2185b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#endif 2195b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2205b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic s32 poseidon_fe_init(struct dvb_frontend *fe) 2215b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 2225b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct poseidon *pd = fe->demodulator_priv; 2235b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 2245b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2255b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#ifdef CONFIG_PM 2265b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd->pm_suspend = pm_dvb_suspend; 2275b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd->pm_resume = pm_dvb_resume; 2285b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie#endif 2295b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie memset(&pd_dvb->fe_param, 0, 2302827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehab sizeof(struct dtv_frontend_properties)); 2315b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 2325b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 2335b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2347c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehabstatic int poseidon_get_fe(struct dvb_frontend *fe) 2355b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 2367c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehab struct dtv_frontend_properties *fep = &fe->dtv_property_cache; 2375b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct poseidon *pd = fe->demodulator_priv; 2385b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 2395b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2405b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie memcpy(fep, &pd_dvb->fe_param, sizeof(*fep)); 2415b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 2425b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 2435b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2445b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int poseidon_fe_get_tune_settings(struct dvb_frontend *fe, 2455b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct dvb_frontend_tune_settings *tune) 2465b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 2475b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie tune->min_delay_ms = 1000; 2485b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 2495b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 2505b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2515b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int poseidon_read_status(struct dvb_frontend *fe, fe_status_t *stat) 2525b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 2535b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct poseidon *pd = fe->demodulator_priv; 2545b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie s32 ret = -1, cmd_status; 2555b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct tuner_dtv_sig_stat_s status = {}; 2565b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2575b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (in_hibernation(pd)) 2585b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return -EBUSY; 2595b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_lock(&pd->lock); 2605b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2615b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T, 2625b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie &status, &cmd_status, sizeof(status)); 2635b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret | cmd_status) { 2645b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie log("get tuner status error"); 2655b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto out; 2665b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 2675b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2685b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (debug_mode) 2695b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie log("P : %d, L %d, LB :%d", status.sig_present, 2705b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie status.sig_locked, status.sig_lock_busy); 2715b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2725b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (status.sig_lock_busy) { 2735b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto out; 2745b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } else if (status.sig_present || status.sig_locked) { 2755b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie *stat |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER 2765b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie | FE_HAS_SYNC | FE_HAS_VITERBI; 2775b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } else { 2785b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (fw_delay_overflow(&pd->dvb_data)) 2795b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie *stat |= FE_TIMEDOUT; 2805b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 2815b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieout: 2825b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_unlock(&pd->lock); 2835b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 2845b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 2855b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2865b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int poseidon_read_ber(struct dvb_frontend *fe, u32 *ber) 2875b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 2885b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct poseidon *pd = fe->demodulator_priv; 2895b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct tuner_ber_rate_s tlg_ber = {}; 2905b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie s32 ret = -1, cmd_status; 2915b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 2925b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_lock(&pd->lock); 2935b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = send_get_req(pd, TUNER_BER_RATE, 0, 2945b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie &tlg_ber, &cmd_status, sizeof(tlg_ber)); 2955b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret | cmd_status) 2965b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto out; 2975b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie *ber = tlg_ber.ber_rate; 2985b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieout: 2995b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_unlock(&pd->lock); 3005b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 3015b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 3025b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3035b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic s32 poseidon_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 3045b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 3055b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct poseidon *pd = fe->demodulator_priv; 3065b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct tuner_dtv_sig_stat_s status = {}; 3075b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie s32 ret = 0, cmd_status; 3085b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3095b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_lock(&pd->lock); 3105b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T, 3115b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie &status, &cmd_status, sizeof(status)); 3125b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret | cmd_status) 3135b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto out; 3145b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if ((status.sig_present || status.sig_locked) && !status.sig_strength) 3155b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie *strength = 0xFFFF; 3165b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie else 3175b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie *strength = status.sig_strength; 3185b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieout: 3195b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_unlock(&pd->lock); 3205b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 3215b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 3225b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3235b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int poseidon_read_snr(struct dvb_frontend *fe, u16 *snr) 3245b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 3255b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 3265b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 3275b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3285b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int poseidon_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) 3295b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 3305b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie *unc = 0; 3315b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 3325b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 3335b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3345b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic struct dvb_frontend_ops poseidon_frontend_ops = { 3352827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehab .delsys = { SYS_DVBT }, 3365b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .info = { 3375b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .name = "Poseidon DVB-T", 3385b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .frequency_min = 174000000, 3395b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .frequency_max = 862000000, 3405b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .frequency_stepsize = 62500,/* FIXME */ 3415b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .caps = FE_CAN_INVERSION_AUTO | 3425b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 3435b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 3445b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | 3455b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | 3465b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie FE_CAN_GUARD_INTERVAL_AUTO | 3475b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie FE_CAN_RECOVER | 3485b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie FE_CAN_HIERARCHY_AUTO, 3495b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie }, 3505b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3515b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .release = poseidon_fe_release, 3525b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3535b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .init = poseidon_fe_init, 3545b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .sleep = poseidon_fe_sleep, 3555b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3562827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehab .set_frontend = poseidon_set_fe, 3572827e1ff8692289a9767ab15be9671bb8df77f79Mauro Carvalho Chehab .get_frontend = poseidon_get_fe, 3585b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .get_tune_settings = poseidon_fe_get_tune_settings, 3595b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3605b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .read_status = poseidon_read_status, 3615b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .read_ber = poseidon_read_ber, 3625b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .read_signal_strength = poseidon_read_signal_strength, 3635b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .read_snr = poseidon_read_snr, 3645b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .read_ucblocks = poseidon_read_unc_blocks, 3655b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3665b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie .ts_bus_ctrl = poseidon_ts_bus_ctrl, 3675b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie}; 3685b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3695b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic void dvb_urb_irq(struct urb *urb) 3705b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 3715b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = urb->context; 3725b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie int len = urb->transfer_buffer_length; 3735b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct dvb_demux *demux = &pd_dvb->demux; 3745b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie s32 ret; 3755b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3765b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (!pd_dvb->is_streaming || urb->status) { 3775b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (urb->status == -EPROTO) 3785b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto resend; 3795b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return; 3805b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 3815b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3825b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (urb->actual_length == len) 3835b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_dmx_swfilter(demux, urb->transfer_buffer, len); 3845b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie else if (urb->actual_length == len - 4) { 3855b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie int offset; 3865b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie u8 *buf = urb->transfer_buffer; 3875b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 3885b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie /* 3895b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie * The packet size is 512, 3905b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie * last packet contains 456 bytes tsp data 3915b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie */ 3925b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie for (offset = 456; offset < len; offset += 512) { 3935b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (!strncmp(buf + offset, "DVHS", 4)) { 3945b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_dmx_swfilter(demux, buf, offset); 3955b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (len > offset + 52 + 4) { 3965b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie /*16 bytes trailer + 36 bytes padding */ 3975b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie buf += offset + 52; 3985b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie len -= offset + 52 + 4; 3995b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_dmx_swfilter(demux, buf, len); 4005b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 4015b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie break; 4025b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 4035b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 4045b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 4055b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4065b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieresend: 4075b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = usb_submit_urb(urb, GFP_ATOMIC); 4085b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret) 4095b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie log(" usb_submit_urb failed: error %d", ret); 4105b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 4115b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4125b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int dvb_urb_init(struct pd_dvb_adapter *pd_dvb) 4135b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 4145b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (pd_dvb->urb_array[0]) 4155b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 4165b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4175b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie alloc_bulk_urbs_generic(pd_dvb->urb_array, DVB_SBUF_NUM, 4185b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->pd_device->udev, pd_dvb->ep_addr, 4195b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie DVB_URB_BUF_SIZE, GFP_KERNEL, 4205b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_urb_irq, pd_dvb); 4215b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 4225b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 4235b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4245b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb) 4255b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 4265b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie free_all_urb_generic(pd_dvb->urb_array, DVB_SBUF_NUM); 4275b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 4285b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4295b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb) 4305b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 4315b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct poseidon *pd = pd_dvb->pd_device; 4325b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie int ret = 0; 4335b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4345b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (pd->state & POSEIDON_STATE_DISCONNECT) 4355b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return -ENODEV; 4365b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4375b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_lock(&pd->lock); 4385b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (!pd_dvb->is_streaming) { 4395b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie s32 i, cmd_status = 0; 4405b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie /* 4415b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie * Once upon a time, there was a difficult bug lying here. 4425b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie * ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status); 4435b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie */ 4445b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4455b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = send_set_req(pd, PLAY_SERVICE, 1, &cmd_status); 4465b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret | cmd_status) 4475b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto out; 4485b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4495b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = dvb_urb_init(pd_dvb); 4505b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret < 0) 4515b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto out; 4525b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4535b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->is_streaming = 1; 4545b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie for (i = 0; i < DVB_SBUF_NUM; i++) { 4555b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = usb_submit_urb(pd_dvb->urb_array[i], 4565b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie GFP_KERNEL); 4575b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret) { 4585b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie log(" submit urb error %d", ret); 4595b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto out; 4605b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 4615b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 4625b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 4635b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieout: 4645b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_unlock(&pd->lock); 4655b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 4665b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 4675b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4685b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijievoid dvb_stop_streaming(struct pd_dvb_adapter *pd_dvb) 4695b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 4705b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct poseidon *pd = pd_dvb->pd_device; 4715b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4725b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_lock(&pd->lock); 4735b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (pd_dvb->is_streaming) { 4745b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie s32 i, ret, cmd_status = 0; 4755b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4765b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->is_streaming = 0; 4775b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4785b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie for (i = 0; i < DVB_SBUF_NUM; i++) 4795b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (pd_dvb->urb_array[i]) 4805b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie usb_kill_urb(pd_dvb->urb_array[i]); 4815b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4825b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP, 4835b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie &cmd_status); 4845b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret | cmd_status) 4855b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie log("error"); 4865b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 4875b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie mutex_unlock(&pd->lock); 4885b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 4895b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4905b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int pd_start_feed(struct dvb_demux_feed *feed) 4915b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 4925b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = feed->demux->priv; 4935b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie int ret = 0; 4945b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 4955b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (!pd_dvb) 4965b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return -1; 4975b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (atomic_inc_return(&pd_dvb->active_feed) == 1) 4985b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = dvb_start_streaming(pd_dvb); 4995b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 5005b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 5015b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5025b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijiestatic int pd_stop_feed(struct dvb_demux_feed *feed) 5035b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 5045b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = feed->demux->priv; 5055b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5065b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (!pd_dvb) 5075b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return -1; 5085b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (atomic_dec_and_test(&pd_dvb->active_feed)) 5095b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_stop_streaming(pd_dvb); 5105b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 5115b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 5125b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5135b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang ShijieDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 5145b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieint pd_dvb_usb_device_init(struct poseidon *pd) 5155b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 5165b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 5175b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct dvb_demux *dvbdemux; 5185b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie int ret = 0; 5195b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5205b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->ep_addr = 0x82; 5215b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie atomic_set(&pd_dvb->users, 0); 5225b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie atomic_set(&pd_dvb->active_feed, 0); 5235b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->pd_device = pd; 5245b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5255b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = dvb_register_adapter(&pd_dvb->dvb_adap, 5265b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie "Poseidon dvbt adapter", 5275b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie THIS_MODULE, 5285b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie NULL /* for hibernation correctly*/, 5295b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie adapter_nr); 5305b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret < 0) 5315b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto error1; 5325b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5335b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie /* register frontend */ 5345b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->dvb_fe.demodulator_priv = pd; 5355b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie memcpy(&pd_dvb->dvb_fe.ops, &poseidon_frontend_ops, 5365b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie sizeof(struct dvb_frontend_ops)); 5375b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = dvb_register_frontend(&pd_dvb->dvb_adap, &pd_dvb->dvb_fe); 5385b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret < 0) 5395b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto error2; 5405b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5415b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie /* register demux device */ 5425b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvbdemux = &pd_dvb->demux; 5435b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvbdemux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; 5445b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvbdemux->priv = pd_dvb; 5455b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvbdemux->feednum = dvbdemux->filternum = 64; 5465b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvbdemux->start_feed = pd_start_feed; 5475b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvbdemux->stop_feed = pd_stop_feed; 5485b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvbdemux->write_to_decoder = NULL; 5495b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5505b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = dvb_dmx_init(dvbdemux); 5515b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret < 0) 5525b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto error3; 5535b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5545b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->dmxdev.filternum = pd_dvb->demux.filternum; 5555b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->dmxdev.demux = &pd_dvb->demux.dmx; 5565b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb->dmxdev.capabilities = 0; 5575b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5585b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie ret = dvb_dmxdev_init(&pd_dvb->dmxdev, &pd_dvb->dvb_adap); 5595b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie if (ret < 0) 5605b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie goto error3; 5615b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return 0; 5625b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5635b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieerror3: 5645b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_unregister_frontend(&pd_dvb->dvb_fe); 5655b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieerror2: 5665b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_unregister_adapter(&pd_dvb->dvb_adap); 5675b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieerror1: 5685b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return ret; 5695b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 5705b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5715b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijievoid pd_dvb_usb_device_exit(struct poseidon *pd) 5725b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 5735b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 5745b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5755b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie while (atomic_read(&pd_dvb->users) != 0 5765b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie || atomic_read(&pd_dvb->active_feed) != 0) { 5775b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie set_current_state(TASK_INTERRUPTIBLE); 5785b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie schedule_timeout(HZ); 5795b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie } 5805b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_dmxdev_release(&pd_dvb->dmxdev); 5815b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_unregister_frontend(&pd_dvb->dvb_fe); 5825b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_unregister_adapter(&pd_dvb->dvb_adap); 5835b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie pd_dvb_usb_device_cleanup(pd); 5845b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 5855b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5865b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijievoid pd_dvb_usb_device_cleanup(struct poseidon *pd) 5875b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 5885b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; 5895b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5905b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie dvb_urb_cleanup(pd_dvb); 5915b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 5925b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie 5935b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijieint pd_dvb_get_adapter_num(struct pd_dvb_adapter *pd_dvb) 5945b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie{ 5955b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie return pd_dvb->dvb_adap.num; 5965b3f03f044ad6dffc8cd8c9c50bc5d7769cbd89fHuang Shijie} 597