Re: [PATCH 10/11] add DVB-T support for tlg2300

2009-12-09 Thread Mauro Carvalho Chehab
Huang Shijie wrote:
> This module contains the code for DVB-T.
> 
> Signed-off-by: Huang Shijie 
> ---
>  drivers/media/video/tlg2300/pd-dvb.c |  649 
> ++
>  1 files changed, 649 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/media/video/tlg2300/pd-dvb.c
> 
> diff --git a/drivers/media/video/tlg2300/pd-dvb.c 
> b/drivers/media/video/tlg2300/pd-dvb.c
> new file mode 100644
> index 000..933fff0
> --- /dev/null
> +++ b/drivers/media/video/tlg2300/pd-dvb.c
> @@ -0,0 +1,649 @@
> +#include "pd-common.h"
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "vendorcmds.h"
> +#include 
> +#include 
> +
> +static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb);
> +
> +static int dvb_bandwidth[][2] = {
> + { TLG_BW_8, BANDWIDTH_8_MHZ },
> + { TLG_BW_7, BANDWIDTH_7_MHZ },
> + { TLG_BW_6, BANDWIDTH_6_MHZ }
> +};
> +static int dvb_bandwidth_length = ARRAY_SIZE(dvb_bandwidth);
> +
> +static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb);
> +static int poseidon_check_mode_dvbt(struct poseidon *pd)
> +{
> + s32 ret = 0, cmd_status = 0;
> +
> + set_current_state(TASK_INTERRUPTIBLE);
> + schedule_timeout(HZ/4);
> +
> + ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE);
> + if (ret != 0)
> + return ret;
> +
> + ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T);
> + if (ret)
> + return ret;
> +
> + /* signal source */
> + ret = send_set_req(pd, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &cmd_status);
> + if (ret|cmd_status)
> + return ret;
> +
> + return 0;
> +}
> +
> +/* acquire :
> + *   1 == open
> + *   0 == release
> + */
> +static int poseidon_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
> +{
> + struct poseidon *pd = fe->demodulator_priv;
> + struct pd_dvb_adapter *pd_dvb;
> + int ret = 0;
> +
> + if (!pd)
> + return -ENODEV;
> +
> + pd_dvb = container_of(fe, struct pd_dvb_adapter, dvb_fe);
> + if (acquire) {
> + mutex_lock(&pd->lock);
> + if (pd->state & POSEIDON_STATE_DISCONNECT) {
> + ret = -ENODEV;
> + goto open_out;
> + }
> +
> + if (pd->state && !(pd->state & POSEIDON_STATE_DVBT)) {
> + ret = -EBUSY;
> + goto open_out;
> + }
> +
> + usb_autopm_get_interface(pd->interface);
> + if (0 == pd->state) {
> + ret = poseidon_check_mode_dvbt(pd);
> + if (ret < 0)
> + goto open_out;
> + pd->state |= POSEIDON_STATE_DVBT;
> + pd_dvb->bandwidth = 0;
> + pd_dvb->prev_freq = 0;
> + }
> + atomic_inc(&pd_dvb->users);
> + kref_get(&pd->kref);
> +open_out:
> + mutex_unlock(&pd->lock);
> + } else {
> + dvb_stop_streaming(pd_dvb);
> +
> + if (atomic_dec_and_test(&pd_dvb->users)) {
> + mutex_lock(&pd->lock);
> + pd->state &= ~POSEIDON_STATE_DVBT;
> + mutex_unlock(&pd->lock);
> + }
> + kref_put(&pd->kref, poseidon_delete);
> + usb_autopm_put_interface(pd->interface);
> + }
> + return ret;
> +}
> +
> +static void poseidon_fe_release(struct dvb_frontend *fe)
> +{
> + struct poseidon *pd = fe->demodulator_priv;
> +
> +#ifdef CONFIG_PM
> + pd->pm_suspend = NULL;
> + pd->pm_resume  = NULL;
> +#endif
> +}
> +
> +static s32 poseidon_fe_sleep(struct dvb_frontend *fe)
> +{
> + return 0;
> +}
> +
> +/*
> + * return true if we can satisfy the conditions, else return false.
> + */
> +static bool check_scan_ok(__u32 freq, int bandwidth,
> + struct pd_dvb_adapter *adapter)
> +{
> + if (bandwidth < 0)
> + return false;
> +
> + if (adapter->prev_freq == freq
> + && adapter->bandwidth == bandwidth) {
> + long nl = jiffies - adapter->last_jiffies;
> + unsigned int msec ;
> +
> + msec = jiffies_to_msecs(abs(nl));
> + return msec > 15000 ? true : false;
> + }
> + return true;
> +}
> +
> +/*
> + * Check if the firmware delays too long for an invalid frequency.
> + */
> +static int fw_delay_overflow(struct pd_dvb_adapter *adapter)
> +{
> + long nl = jiffies - adapter->last_jiffies;
> + unsigned int msec ;
> +
> + msec = jiffies_to_msecs(abs(nl));
> + return msec > 800 ? true : false;
> +}
> +
> +static int pm_dvb_suspend(struct poseidon *pd)
> +{
> + struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
> + dvb_stop_streaming(pd_dvb);
> + dvb_urb_cleanup(pd_dvb);
> + mdelay(2000);

Use msleep()

> + return 0;
> +}
> +
> +
> +static int poseidon_set_fe(struct dvb_frontend *fe,
> + struct dvb_frontend_parameters *fep)
> +{
>

[PATCH 10/11] add DVB-T support for tlg2300

2009-11-19 Thread Huang Shijie
This module contains the code for DVB-T.

Signed-off-by: Huang Shijie 
---
 drivers/media/video/tlg2300/pd-dvb.c |  649 ++
 1 files changed, 649 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/tlg2300/pd-dvb.c

diff --git a/drivers/media/video/tlg2300/pd-dvb.c 
b/drivers/media/video/tlg2300/pd-dvb.c
new file mode 100644
index 000..933fff0
--- /dev/null
+++ b/drivers/media/video/tlg2300/pd-dvb.c
@@ -0,0 +1,649 @@
+#include "pd-common.h"
+#include 
+#include 
+#include 
+#include 
+
+#include "vendorcmds.h"
+#include 
+#include 
+
+static void dvb_urb_cleanup(struct pd_dvb_adapter *pd_dvb);
+
+static int dvb_bandwidth[][2] = {
+   { TLG_BW_8, BANDWIDTH_8_MHZ },
+   { TLG_BW_7, BANDWIDTH_7_MHZ },
+   { TLG_BW_6, BANDWIDTH_6_MHZ }
+};
+static int dvb_bandwidth_length = ARRAY_SIZE(dvb_bandwidth);
+
+static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb);
+static int poseidon_check_mode_dvbt(struct poseidon *pd)
+{
+   s32 ret = 0, cmd_status = 0;
+
+   set_current_state(TASK_INTERRUPTIBLE);
+   schedule_timeout(HZ/4);
+
+   ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE);
+   if (ret != 0)
+   return ret;
+
+   ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T);
+   if (ret)
+   return ret;
+
+   /* signal source */
+   ret = send_set_req(pd, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &cmd_status);
+   if (ret|cmd_status)
+   return ret;
+
+   return 0;
+}
+
+/* acquire :
+ * 1 == open
+ * 0 == release
+ */
+static int poseidon_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
+{
+   struct poseidon *pd = fe->demodulator_priv;
+   struct pd_dvb_adapter *pd_dvb;
+   int ret = 0;
+
+   if (!pd)
+   return -ENODEV;
+
+   pd_dvb = container_of(fe, struct pd_dvb_adapter, dvb_fe);
+   if (acquire) {
+   mutex_lock(&pd->lock);
+   if (pd->state & POSEIDON_STATE_DISCONNECT) {
+   ret = -ENODEV;
+   goto open_out;
+   }
+
+   if (pd->state && !(pd->state & POSEIDON_STATE_DVBT)) {
+   ret = -EBUSY;
+   goto open_out;
+   }
+
+   usb_autopm_get_interface(pd->interface);
+   if (0 == pd->state) {
+   ret = poseidon_check_mode_dvbt(pd);
+   if (ret < 0)
+   goto open_out;
+   pd->state |= POSEIDON_STATE_DVBT;
+   pd_dvb->bandwidth = 0;
+   pd_dvb->prev_freq = 0;
+   }
+   atomic_inc(&pd_dvb->users);
+   kref_get(&pd->kref);
+open_out:
+   mutex_unlock(&pd->lock);
+   } else {
+   dvb_stop_streaming(pd_dvb);
+
+   if (atomic_dec_and_test(&pd_dvb->users)) {
+   mutex_lock(&pd->lock);
+   pd->state &= ~POSEIDON_STATE_DVBT;
+   mutex_unlock(&pd->lock);
+   }
+   kref_put(&pd->kref, poseidon_delete);
+   usb_autopm_put_interface(pd->interface);
+   }
+   return ret;
+}
+
+static void poseidon_fe_release(struct dvb_frontend *fe)
+{
+   struct poseidon *pd = fe->demodulator_priv;
+
+#ifdef CONFIG_PM
+   pd->pm_suspend = NULL;
+   pd->pm_resume  = NULL;
+#endif
+}
+
+static s32 poseidon_fe_sleep(struct dvb_frontend *fe)
+{
+   return 0;
+}
+
+/*
+ * return true if we can satisfy the conditions, else return false.
+ */
+static bool check_scan_ok(__u32 freq, int bandwidth,
+   struct pd_dvb_adapter *adapter)
+{
+   if (bandwidth < 0)
+   return false;
+
+   if (adapter->prev_freq == freq
+   && adapter->bandwidth == bandwidth) {
+   long nl = jiffies - adapter->last_jiffies;
+   unsigned int msec ;
+
+   msec = jiffies_to_msecs(abs(nl));
+   return msec > 15000 ? true : false;
+   }
+   return true;
+}
+
+/*
+ * Check if the firmware delays too long for an invalid frequency.
+ */
+static int fw_delay_overflow(struct pd_dvb_adapter *adapter)
+{
+   long nl = jiffies - adapter->last_jiffies;
+   unsigned int msec ;
+
+   msec = jiffies_to_msecs(abs(nl));
+   return msec > 800 ? true : false;
+}
+
+static int pm_dvb_suspend(struct poseidon *pd)
+{
+   struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
+   dvb_stop_streaming(pd_dvb);
+   dvb_urb_cleanup(pd_dvb);
+   mdelay(2000);
+   return 0;
+}
+
+
+static int poseidon_set_fe(struct dvb_frontend *fe,
+   struct dvb_frontend_parameters *fep)
+{
+   s32 ret = 0, cmd_status = 0;
+   s32 i, bandwidth = -1;
+   struct poseidon *pd = fe->demodulator_priv;
+   struct pd_dvb_adapter *pd_dvb = &pd->dvb_data;
+
+   if (in_hibernation(pd))
+