2525#include <linux/moduleparam.h>
2626#include <linux/videodev2.h>
2727#include <linux/delay.h>
28+ #include <linux/workqueue.h>
2829#include <linux/dvb/frontend.h>
2930#include <linux/i2c.h>
3031
@@ -65,12 +66,18 @@ struct xc5000_priv {
6566 u16 pll_register_no ;
6667 u8 init_status_supported ;
6768 u8 fw_checksum_supported ;
69+
70+ struct dvb_frontend * fe ;
71+ struct delayed_work timer_sleep ;
6872};
6973
7074/* Misc Defines */
7175#define MAX_TV_STANDARD 24
7276#define XC_MAX_I2C_WRITE_LENGTH 64
7377
78+ /* Time to suspend after the .sleep callback is called */
79+ #define XC5000_SLEEP_TIME 5000 /* ms */
80+
7481/* Signal Types */
7582#define XC_RF_MODE_AIR 0
7683#define XC_RF_MODE_CABLE 1
@@ -1096,6 +1103,8 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
10961103 u16 pll_lock_status ;
10971104 u16 fw_ck ;
10981105
1106+ cancel_delayed_work (& priv -> timer_sleep );
1107+
10991108 if (force || xc5000_is_firmware_loaded (fe ) != 0 ) {
11001109
11011110fw_retry :
@@ -1164,27 +1173,39 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
11641173 return ret ;
11651174}
11661175
1167- static int xc5000_sleep (struct dvb_frontend * fe )
1176+ static void xc5000_do_timer_sleep (struct work_struct * timer_sleep )
11681177{
1178+ struct xc5000_priv * priv = container_of (timer_sleep , struct xc5000_priv ,
1179+ timer_sleep .work );
1180+ struct dvb_frontend * fe = priv -> fe ;
11691181 int ret ;
11701182
11711183 dprintk (1 , "%s()\n" , __func__ );
11721184
1173- /* Avoid firmware reload on slow devices */
1174- if (no_poweroff )
1175- return 0 ;
1176-
11771185 /* According to Xceive technical support, the "powerdown" register
11781186 was removed in newer versions of the firmware. The "supported"
11791187 way to sleep the tuner is to pull the reset pin low for 10ms */
11801188 ret = xc5000_tuner_reset (fe );
1181- if (ret != 0 ) {
1189+ if (ret != 0 )
11821190 printk (KERN_ERR
11831191 "xc5000: %s() unable to shutdown tuner\n" ,
11841192 __func__ );
1185- return - EREMOTEIO ;
1186- } else
1193+ }
1194+
1195+ static int xc5000_sleep (struct dvb_frontend * fe )
1196+ {
1197+ struct xc5000_priv * priv = fe -> tuner_priv ;
1198+
1199+ dprintk (1 , "%s()\n" , __func__ );
1200+
1201+ /* Avoid firmware reload on slow devices */
1202+ if (no_poweroff )
11871203 return 0 ;
1204+
1205+ schedule_delayed_work (& priv -> timer_sleep ,
1206+ msecs_to_jiffies (XC5000_SLEEP_TIME ));
1207+
1208+ return 0 ;
11881209}
11891210
11901211static int xc5000_init (struct dvb_frontend * fe )
@@ -1211,8 +1232,10 @@ static int xc5000_release(struct dvb_frontend *fe)
12111232
12121233 mutex_lock (& xc5000_list_mutex );
12131234
1214- if (priv )
1235+ if (priv ) {
1236+ cancel_delayed_work (& priv -> timer_sleep );
12151237 hybrid_tuner_release_state (priv );
1238+ }
12161239
12171240 mutex_unlock (& xc5000_list_mutex );
12181241
@@ -1284,6 +1307,8 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
12841307 /* new tuner instance */
12851308 priv -> bandwidth = 6000000 ;
12861309 fe -> tuner_priv = priv ;
1310+ priv -> fe = fe ;
1311+ INIT_DELAYED_WORK (& priv -> timer_sleep , xc5000_do_timer_sleep );
12871312 break ;
12881313 default :
12891314 /* existing tuner instance */
0 commit comments