aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/tuners/xc5000.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 8df92619883f..2b3d514be672 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -25,6 +25,7 @@
25#include <linux/moduleparam.h> 25#include <linux/moduleparam.h>
26#include <linux/videodev2.h> 26#include <linux/videodev2.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/workqueue.h>
28#include <linux/dvb/frontend.h> 29#include <linux/dvb/frontend.h>
29#include <linux/i2c.h> 30#include <linux/i2c.h>
30 31
@@ -65,12 +66,18 @@ struct xc5000_priv {
65 u16 pll_register_no; 66 u16 pll_register_no;
66 u8 init_status_supported; 67 u8 init_status_supported;
67 u8 fw_checksum_supported; 68 u8 fw_checksum_supported;
69
70 struct dvb_frontend *fe;
71 struct delayed_work timer_sleep;
68}; 72};
69 73
70/* Misc Defines */ 74/* Misc Defines */
71#define MAX_TV_STANDARD 24 75#define MAX_TV_STANDARD 24
72#define XC_MAX_I2C_WRITE_LENGTH 64 76#define XC_MAX_I2C_WRITE_LENGTH 64
73 77
78/* Time to suspend after the .sleep callback is called */
79#define XC5000_SLEEP_TIME 5000 /* ms */
80
74/* Signal Types */ 81/* Signal Types */
75#define XC_RF_MODE_AIR 0 82#define XC_RF_MODE_AIR 0
76#define XC_RF_MODE_CABLE 1 83#define XC_RF_MODE_CABLE 1
@@ -1096,6 +1103,8 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
1096 u16 pll_lock_status; 1103 u16 pll_lock_status;
1097 u16 fw_ck; 1104 u16 fw_ck;
1098 1105
1106 cancel_delayed_work(&priv->timer_sleep);
1107
1099 if (force || xc5000_is_firmware_loaded(fe) != 0) { 1108 if (force || xc5000_is_firmware_loaded(fe) != 0) {
1100 1109
1101fw_retry: 1110fw_retry:
@@ -1164,27 +1173,39 @@ fw_retry:
1164 return ret; 1173 return ret;
1165} 1174}
1166 1175
1167static int xc5000_sleep(struct dvb_frontend *fe) 1176static void xc5000_do_timer_sleep(struct work_struct *timer_sleep)
1168{ 1177{
1178 struct xc5000_priv *priv =container_of(timer_sleep, struct xc5000_priv,
1179 timer_sleep.work);
1180 struct dvb_frontend *fe = priv->fe;
1169 int ret; 1181 int ret;
1170 1182
1171 dprintk(1, "%s()\n", __func__); 1183 dprintk(1, "%s()\n", __func__);
1172 1184
1173 /* Avoid firmware reload on slow devices */
1174 if (no_poweroff)
1175 return 0;
1176
1177 /* According to Xceive technical support, the "powerdown" register 1185 /* According to Xceive technical support, the "powerdown" register
1178 was removed in newer versions of the firmware. The "supported" 1186 was removed in newer versions of the firmware. The "supported"
1179 way to sleep the tuner is to pull the reset pin low for 10ms */ 1187 way to sleep the tuner is to pull the reset pin low for 10ms */
1180 ret = xc5000_tuner_reset(fe); 1188 ret = xc5000_tuner_reset(fe);
1181 if (ret != 0) { 1189 if (ret != 0)
1182 printk(KERN_ERR 1190 printk(KERN_ERR
1183 "xc5000: %s() unable to shutdown tuner\n", 1191 "xc5000: %s() unable to shutdown tuner\n",
1184 __func__); 1192 __func__);
1185 return -EREMOTEIO; 1193}
1186 } else 1194
1195static 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)
1187 return 0; 1203 return 0;
1204
1205 schedule_delayed_work(&priv->timer_sleep,
1206 msecs_to_jiffies(XC5000_SLEEP_TIME));
1207
1208 return 0;
1188} 1209}
1189 1210
1190static int xc5000_init(struct dvb_frontend *fe) 1211static int xc5000_init(struct dvb_frontend *fe)
@@ -1211,8 +1232,10 @@ static int xc5000_release(struct dvb_frontend *fe)
1211 1232
1212 mutex_lock(&xc5000_list_mutex); 1233 mutex_lock(&xc5000_list_mutex);
1213 1234
1214 if (priv) 1235 if (priv) {
1236 cancel_delayed_work(&priv->timer_sleep);
1215 hybrid_tuner_release_state(priv); 1237 hybrid_tuner_release_state(priv);
1238 }
1216 1239
1217 mutex_unlock(&xc5000_list_mutex); 1240 mutex_unlock(&xc5000_list_mutex);
1218 1241
@@ -1284,6 +1307,8 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
1284 /* new tuner instance */ 1307 /* new tuner instance */
1285 priv->bandwidth = 6000000; 1308 priv->bandwidth = 6000000;
1286 fe->tuner_priv = priv; 1309 fe->tuner_priv = priv;
1310 priv->fe = fe;
1311 INIT_DELAYED_WORK(&priv->timer_sleep, xc5000_do_timer_sleep);
1287 break; 1312 break;
1288 default: 1313 default:
1289 /* existing tuner instance */ 1314 /* existing tuner instance */