V4L/DVB (8735): dtv5100: replace dummy frontend by zl10353

Remove the dtv5100-fe.c dummy frontend and replace it by the real frontend for the chipset.

Signed-off-by: Antoine Jacquet <royale@zerezo.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.c b/drivers/media/dvb/dvb-usb/dtv5100.c
index f89d017..7168a49c 100644
--- a/drivers/media/dvb/dvb-usb/dtv5100.c
+++ b/drivers/media/dvb/dvb-usb/dtv5100.c
@@ -22,6 +22,7 @@
  */
 
 #include "dtv5100.h"
+#include "zl10353.h"
 #include "qt1010.h"
 
 /* debug */
@@ -30,25 +31,44 @@
 MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
-static int dtv5100_read_reg(struct dvb_usb_device *d, u8 addr, u8 reg, u8 *value)
+static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
+			  u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
 {
-	return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
-			       DTV5100_I2C_READ, USB_TYPE_VENDOR|USB_DIR_IN,
-			       0, (addr << 8) + reg, value, 1,
-			       DTV5100_USB_TIMEOUT);
-}
+	u8 request;
+	u8 type;
+	u16 value;
+	u16 index;
 
-static int dtv5100_write_reg(struct dvb_usb_device *d, u8 addr, u8 reg, u8 value)
-{
-	return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
-			       DTV5100_I2C_WRITE, USB_TYPE_VENDOR|USB_DIR_OUT,
-			       value, (addr << 8) + reg, NULL, 0,
+	switch (wlen) {
+	case 1:
+		/* write { reg }, read { value } */
+		request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ :
+							DTV5100_TUNER_READ);
+		type = USB_TYPE_VENDOR|USB_DIR_IN;
+		value = 0;
+		break;
+	case 2:
+		/* write { reg, value } */
+		request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE :
+							DTV5100_TUNER_WRITE);
+		type = USB_TYPE_VENDOR|USB_DIR_OUT;
+		value = wbuf[1];
+		break;
+	default:
+		warn("wlen = %x, aborting.", wlen);
+		return -EINVAL;
+	}
+	index = (addr << 8) + wbuf[0];
+
+	msleep(1); /* avoid I2C errors */
+	return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request,
+			       type, value, index, rbuf, rlen,
 			       DTV5100_USB_TIMEOUT);
 }
 
 /* I2C */
 static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
-			    int num)
+			   int num)
 {
 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
 	int i;
@@ -60,25 +80,16 @@
 		return -EAGAIN;
 
 	for (i = 0; i < num; i++) {
+		/* write/read request */
 		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
-			/* write/read request, 2 messages
-			 *	msg = {
-			 *		{ reg },
-			 *		{ val },
-			 *	}
-			 */
-			if (dtv5100_read_reg(d, msg[i].addr, msg[i].buf[0], msg[i+1].buf) < 0)
+			if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
+					    msg[i].len, msg[i+1].buf,
+					    msg[i+1].len) < 0)
 				break;
 			i++;
-		} else {
-			/* write request, 1 message
-			 *	msg = {
-			 *		{ reg, val },
-			 *	}
-			 */
-			if (dtv5100_write_reg(d, msg[i].addr, msg[i].buf[0], msg[i].buf[1]) < 0)
+		} else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
+					   msg[i].len, NULL, 0) < 0)
 				break;
-		}
 	}
 
 	mutex_unlock(&d->i2c_mutex);
@@ -96,14 +107,27 @@
 };
 
 /* Callbacks for DVB USB */
+static struct zl10353_config dtv5100_zl10353_config = {
+	.demod_address = DTV5100_DEMOD_ADDR,
+	.no_tuner = 1,
+	.parallel_ts = 1,
+};
+
 static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap)
 {
-	adap->fe = dtv5100_fe_attach();
+	adap->fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config,
+		&adap->dev->i2c_adap);
+	if (adap->fe == NULL)
+		return -EIO;
+
+	/* disable i2c gate, or it won't work... is this safe? */
+	adap->fe->ops.i2c_gate_ctrl = NULL;
+
 	return 0;
 }
 
 static struct qt1010_config dtv5100_qt1010_config = {
-	.i2c_address = 0xc4
+	.i2c_address = DTV5100_TUNER_ADDR
 };
 
 static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap)
@@ -122,12 +146,7 @@
 	int i, ret;
 	struct usb_device *udev = interface_to_usbdev(intf);
 
-	ret = dvb_usb_device_init(intf, &dtv5100_properties,
-				  THIS_MODULE, NULL, adapter_nr);
-	if (ret)
-		return ret;
-
-	/* initialize frontend & non qt1010 part? */
+	/* initialize non qt1010/zl10353 part? */
 	for (i = 0; dtv5100_init[i].request; i++)
 	{
 		ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
@@ -140,6 +159,11 @@
 			return ret;
 	}
 
+	ret = dvb_usb_device_init(intf, &dtv5100_properties,
+				  THIS_MODULE, NULL, adapter_nr);
+	if (ret)
+		return ret;
+
 	return 0;
 }