[media] tua9001: implement control pin callbacks

There is three pins used for controlling that tuner.
Implement those using frontend callback.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c
index de26070..6147eee 100644
--- a/drivers/media/tuners/tua9001.c
+++ b/drivers/media/tuners/tua9001.c
@@ -49,10 +49,17 @@
 
 static int tua9001_release(struct dvb_frontend *fe)
 {
+	struct tua9001_priv *priv = fe->tuner_priv;
+	int ret = 0;
+
+	if (fe->callback)
+		ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+				TUA9001_CMD_CEN, 0);
+
 	kfree(fe->tuner_priv);
 	fe->tuner_priv = NULL;
 
-	return 0;
+	return ret;
 }
 
 static int tua9001_init(struct dvb_frontend *fe)
@@ -78,17 +85,40 @@
 		{ 0x34, 0x0a40 },
 	};
 
+	if (fe->callback) {
+		ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+				TUA9001_CMD_RESETN, 0);
+		if (ret < 0)
+			goto err;
+	}
+
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
 
 	for (i = 0; i < ARRAY_SIZE(data); i++) {
 		ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
-		if (ret)
-			break;
+		if (ret < 0)
+			goto err_i2c_gate_ctrl;
 	}
 
+err_i2c_gate_ctrl:
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
+err:
+	if (ret < 0)
+		pr_debug("%s: failed=%d\n", __func__, ret);
+
+	return ret;
+}
+
+static int tua9001_sleep(struct dvb_frontend *fe)
+{
+	struct tua9001_priv *priv = fe->tuner_priv;
+	int ret = 0;
+
+	if (fe->callback)
+		ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+				TUA9001_CMD_RESETN, 1);
 
 	if (ret < 0)
 		pr_debug("%s: failed=%d\n", __func__, ret);
@@ -148,15 +178,29 @@
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
 
+	if (fe->callback) {
+		ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+				TUA9001_CMD_RXEN, 0);
+		if (ret < 0)
+			goto err_i2c_gate_ctrl;
+	}
+
 	for (i = 0; i < ARRAY_SIZE(data); i++) {
 		ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
 		if (ret < 0)
-			break;
+			goto err_i2c_gate_ctrl;
 	}
 
+	if (fe->callback) {
+		ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+				TUA9001_CMD_RXEN, 1);
+		if (ret < 0)
+			goto err_i2c_gate_ctrl;
+	}
+
+err_i2c_gate_ctrl:
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
-
 err:
 	if (ret < 0)
 		pr_debug("%s: failed=%d\n", __func__, ret);
@@ -183,6 +227,7 @@
 	.release = tua9001_release,
 
 	.init = tua9001_init,
+	.sleep = tua9001_sleep,
 	.set_params = tua9001_set_params,
 
 	.get_if_frequency = tua9001_get_if_frequency,
@@ -192,6 +237,7 @@
 		struct i2c_adapter *i2c, struct tua9001_config *cfg)
 {
 	struct tua9001_priv *priv = NULL;
+	int ret;
 
 	priv = kzalloc(sizeof(struct tua9001_priv), GFP_KERNEL);
 	if (priv == NULL)
@@ -200,6 +246,13 @@
 	priv->cfg = cfg;
 	priv->i2c = i2c;
 
+	if (fe->callback) {
+		ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
+				TUA9001_CMD_CEN, 1);
+		if (ret < 0)
+			goto err;
+	}
+
 	printk(KERN_INFO "Infineon TUA 9001 successfully attached.");
 
 	memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops,
@@ -207,6 +260,9 @@
 
 	fe->tuner_priv = priv;
 	return fe;
+err:
+	kfree(priv);
+	return NULL;
 }
 EXPORT_SYMBOL(tua9001_attach);