diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 889d4a817c88..bbf441215e79 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -215,6 +215,11 @@ static void dvb_frontend_init(struct dvb_frontend *fe)
 
 	if (fe->ops->init)
 		fe->ops->init(fe);
+	if (fe->ops->tuner_ops.init) {
+		fe->ops->tuner_ops.init(fe);
+		if (fe->ops->i2c_gate_ctrl)
+			fe->ops->i2c_gate_ctrl(fe, 0);
+	}
 }
 
 void dvb_frontend_reinitialise(struct dvb_frontend *fe)
@@ -571,6 +576,11 @@ static int dvb_frontend_thread(void *data)
 		if (dvb_powerdown_on_sleep)
 			if (fe->ops->set_voltage)
 				fe->ops->set_voltage(fe, SEC_VOLTAGE_OFF);
+		if (fe->ops->tuner_ops.sleep) {
+			fe->ops->tuner_ops.sleep(fe);
+			if (fe->ops->i2c_gate_ctrl)
+				fe->ops->i2c_gate_ctrl(fe, 0);
+		}
 		if (fe->ops->sleep)
 			fe->ops->sleep(fe);
 	}
@@ -1085,6 +1095,11 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
 	mutex_lock(&frontend_mutex);
 	dvb_unregister_device (fepriv->dvbdev);
 	dvb_frontend_stop (fe);
+	if (fe->ops->tuner_ops.release) {
+		fe->ops->tuner_ops.release(fe);
+		if (fe->ops->i2c_gate_ctrl)
+			fe->ops->i2c_gate_ctrl(fe, 0);
+	}
 	if (fe->ops->release)
 		fe->ops->release(fe);
 	else
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 5926a3b745c9..e0148a9e6633 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -49,6 +49,115 @@ struct dvb_frontend_tune_settings {
 
 struct dvb_frontend;
 
+struct dvb_tuner_info {
+	char name[128];
+
+	u32 frequency_min;
+	u32 frequency_max;
+	u32 frequency_step;
+
+	u32 bandwidth_min;
+	u32 bandwidth_max;
+	u32 bandwidth_step;
+};
+
+struct dvb_tuner_ops {
+	/**
+	 * Description of the tuner.
+	 */
+	struct dvb_tuner_info info;
+
+	/**
+	 * Cleanup an attached tuner.
+	 *
+	 * @param fe dvb_frontend structure to clean it up from.
+	 * @return 0 on success, <0 on failure.
+	 */
+	int (*release)(struct dvb_frontend *fe);
+
+	/**
+	 * Initialise a tuner.
+	 *
+	 * @param fe dvb_frontend structure.
+	 * @return 0 on success, <0 on failure.
+	 */
+	int (*init)(struct dvb_frontend *fe);
+
+	/**
+	 * Set a tuner into low power mode.
+	 *
+	 * @param fe dvb_frontend structure.
+	 * @return 0 on success, <0 on failure.
+	 */
+	int (*sleep)(struct dvb_frontend *fe);
+
+	/**
+	 * This is for simple PLLs - set all parameters in one go.
+	 *
+	 * @param fe The dvb_frontend structure.
+	 * @param p The parameters to set.
+	 * @return 0 on success, <0 on failure.
+	 */
+	int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
+
+	/**
+	 * This is support for demods like the mt352 - fills out the supplied buffer with what to write.
+	 *
+	 * @param fe The dvb_frontend structure.
+	 * @param p The parameters to set.
+	 * @param buf The buffer to fill with data. For an i2c tuner, the first byte should be the tuner i2c address in linux format.
+	 * @param buf_len Size of buffer in bytes.
+	 * @return Number of bytes used, or <0 on failure.
+	 */
+	int (*pllbuf)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len);
+
+	/**
+	 * Get the frequency the tuner was actually set to.
+	 *
+	 * @param fe The dvb_frontend structure.
+	 * @param frequency Where to put it.
+	 * @return 0 on success, or <0 on failure.
+	 */
+	int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency);
+
+	/**
+	 * Get the bandwidth the tuner was actually set to.
+	 *
+	 * @param fe The dvb_frontend structure.
+	 * @param bandwidth Where to put it.
+	 * @return 0 on success, or <0 on failure.
+	 */
+	int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
+
+	/**
+	 * Get the tuner's status.
+	 *
+	 * @param fe The dvb_frontend structure.
+	 * @param status Where to put it.
+	 * @return 0 on success, or <0 on failure.
+	 */
+#define TUNER_STATUS_LOCKED 1
+	int (*get_status)(struct dvb_frontend *fe, u32 *status);
+
+	/**
+	 * Set the frequency of the tuner - for complex tuners.
+	 *
+	 * @param fe The dvb_frontend structure.
+	 * @param frequency What to set.
+	 * @return 0 on success, or <0 on failure.
+	 */
+	int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
+
+	/**
+	 * Set the bandwidth of the tuner - for complex tuners.
+	 *
+	 * @param fe The dvb_frontend structure.
+	 * @param bandwidth  What to set.
+	 * @return 0 on success, or <0 on failure.
+	 */
+	int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
+};
+
 struct dvb_frontend_ops {
 
 	struct dvb_frontend_info info;
@@ -86,6 +195,8 @@ struct dvb_frontend_ops {
 	int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
 	int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
 	int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
+
+	struct dvb_tuner_ops tuner_ops;
 };
 
 #define MAX_EVENT 8
@@ -103,6 +214,7 @@ struct dvb_frontend {
 	struct dvb_frontend_ops* ops;
 	struct dvb_adapter *dvb;
 	void* demodulator_priv;
+	void* tuner_priv;
 	void* frontend_priv;
 	void* misc_priv;
 };