1786baecfSMauro Carvalho Chehab /*
2786baecfSMauro Carvalho Chehab  * Afatech AF9035 DVB USB driver
3786baecfSMauro Carvalho Chehab  *
4786baecfSMauro Carvalho Chehab  * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5786baecfSMauro Carvalho Chehab  * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
6786baecfSMauro Carvalho Chehab  *
7786baecfSMauro Carvalho Chehab  *    This program is free software; you can redistribute it and/or modify
8786baecfSMauro Carvalho Chehab  *    it under the terms of the GNU General Public License as published by
9786baecfSMauro Carvalho Chehab  *    the Free Software Foundation; either version 2 of the License, or
10786baecfSMauro Carvalho Chehab  *    (at your option) any later version.
11786baecfSMauro Carvalho Chehab  *
12786baecfSMauro Carvalho Chehab  *    This program is distributed in the hope that it will be useful,
13786baecfSMauro Carvalho Chehab  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
14786baecfSMauro Carvalho Chehab  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15786baecfSMauro Carvalho Chehab  *    GNU General Public License for more details.
16786baecfSMauro Carvalho Chehab  *
17786baecfSMauro Carvalho Chehab  *    You should have received a copy of the GNU General Public License along
18786baecfSMauro Carvalho Chehab  *    with this program; if not, write to the Free Software Foundation, Inc.,
19786baecfSMauro Carvalho Chehab  *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20786baecfSMauro Carvalho Chehab  */
21786baecfSMauro Carvalho Chehab 
22786baecfSMauro Carvalho Chehab #include "af9035.h"
23786baecfSMauro Carvalho Chehab 
247760e148SMauro Carvalho Chehab /* Max transfer size done by I2C transfer functions */
257760e148SMauro Carvalho Chehab #define MAX_XFER_SIZE  64
267760e148SMauro Carvalho Chehab 
27786baecfSMauro Carvalho Chehab DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
28786baecfSMauro Carvalho Chehab 
29786baecfSMauro Carvalho Chehab static u16 af9035_checksum(const u8 *buf, size_t len)
30786baecfSMauro Carvalho Chehab {
31786baecfSMauro Carvalho Chehab 	size_t i;
32786baecfSMauro Carvalho Chehab 	u16 checksum = 0;
33786baecfSMauro Carvalho Chehab 
34786baecfSMauro Carvalho Chehab 	for (i = 1; i < len; i++) {
35786baecfSMauro Carvalho Chehab 		if (i % 2)
36786baecfSMauro Carvalho Chehab 			checksum += buf[i] << 8;
37786baecfSMauro Carvalho Chehab 		else
38786baecfSMauro Carvalho Chehab 			checksum += buf[i];
39786baecfSMauro Carvalho Chehab 	}
40786baecfSMauro Carvalho Chehab 	checksum = ~checksum;
41786baecfSMauro Carvalho Chehab 
42786baecfSMauro Carvalho Chehab 	return checksum;
43786baecfSMauro Carvalho Chehab }
44786baecfSMauro Carvalho Chehab 
45786baecfSMauro Carvalho Chehab static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
46786baecfSMauro Carvalho Chehab {
47786baecfSMauro Carvalho Chehab #define REQ_HDR_LEN 4 /* send header size */
48786baecfSMauro Carvalho Chehab #define ACK_HDR_LEN 3 /* rece header size */
49786baecfSMauro Carvalho Chehab #define CHECKSUM_LEN 2
50786baecfSMauro Carvalho Chehab #define USB_TIMEOUT 2000
51786baecfSMauro Carvalho Chehab 	struct state *state = d_to_priv(d);
522b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
53786baecfSMauro Carvalho Chehab 	int ret, wlen, rlen;
54786baecfSMauro Carvalho Chehab 	u16 checksum, tmp_checksum;
55786baecfSMauro Carvalho Chehab 
563484d37aSAntti Palosaari 	mutex_lock(&d->usb_mutex);
573484d37aSAntti Palosaari 
58786baecfSMauro Carvalho Chehab 	/* buffer overflow check */
59786baecfSMauro Carvalho Chehab 	if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
60786baecfSMauro Carvalho Chehab 			req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
612b987ea7SAntti Palosaari 		dev_err(&intf->dev, "too much data wlen=%d rlen=%d\n",
622b987ea7SAntti Palosaari 			req->wlen, req->rlen);
633484d37aSAntti Palosaari 		ret = -EINVAL;
640170a39bSWei Yongjun 		goto exit;
65786baecfSMauro Carvalho Chehab 	}
66786baecfSMauro Carvalho Chehab 
673484d37aSAntti Palosaari 	state->buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1;
683484d37aSAntti Palosaari 	state->buf[1] = req->mbox;
693484d37aSAntti Palosaari 	state->buf[2] = req->cmd;
703484d37aSAntti Palosaari 	state->buf[3] = state->seq++;
713484d37aSAntti Palosaari 	memcpy(&state->buf[REQ_HDR_LEN], req->wbuf, req->wlen);
72786baecfSMauro Carvalho Chehab 
73786baecfSMauro Carvalho Chehab 	wlen = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN;
74786baecfSMauro Carvalho Chehab 	rlen = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN;
75786baecfSMauro Carvalho Chehab 
76786baecfSMauro Carvalho Chehab 	/* calc and add checksum */
773484d37aSAntti Palosaari 	checksum = af9035_checksum(state->buf, state->buf[0] - 1);
783484d37aSAntti Palosaari 	state->buf[state->buf[0] - 1] = (checksum >> 8);
793484d37aSAntti Palosaari 	state->buf[state->buf[0] - 0] = (checksum & 0xff);
80786baecfSMauro Carvalho Chehab 
81786baecfSMauro Carvalho Chehab 	/* no ack for these packets */
82786baecfSMauro Carvalho Chehab 	if (req->cmd == CMD_FW_DL)
83786baecfSMauro Carvalho Chehab 		rlen = 0;
84786baecfSMauro Carvalho Chehab 
853484d37aSAntti Palosaari 	ret = dvb_usbv2_generic_rw_locked(d,
863484d37aSAntti Palosaari 			state->buf, wlen, state->buf, rlen);
87786baecfSMauro Carvalho Chehab 	if (ret)
880170a39bSWei Yongjun 		goto exit;
89786baecfSMauro Carvalho Chehab 
90786baecfSMauro Carvalho Chehab 	/* no ack for those packets */
91786baecfSMauro Carvalho Chehab 	if (req->cmd == CMD_FW_DL)
92786baecfSMauro Carvalho Chehab 		goto exit;
93786baecfSMauro Carvalho Chehab 
94786baecfSMauro Carvalho Chehab 	/* verify checksum */
953484d37aSAntti Palosaari 	checksum = af9035_checksum(state->buf, rlen - 2);
963484d37aSAntti Palosaari 	tmp_checksum = (state->buf[rlen - 2] << 8) | state->buf[rlen - 1];
97786baecfSMauro Carvalho Chehab 	if (tmp_checksum != checksum) {
982b987ea7SAntti Palosaari 		dev_err(&intf->dev, "command=%02x checksum mismatch (%04x != %04x)\n",
992b987ea7SAntti Palosaari 			req->cmd, tmp_checksum, checksum);
100786baecfSMauro Carvalho Chehab 		ret = -EIO;
1010170a39bSWei Yongjun 		goto exit;
102786baecfSMauro Carvalho Chehab 	}
103786baecfSMauro Carvalho Chehab 
104786baecfSMauro Carvalho Chehab 	/* check status */
1053484d37aSAntti Palosaari 	if (state->buf[2]) {
1061bfd5294SAntti Palosaari 		/* fw returns status 1 when IR code was not received */
1070170a39bSWei Yongjun 		if (req->cmd == CMD_IR_GET || state->buf[2] == 1) {
1080170a39bSWei Yongjun 			ret = 1;
1090170a39bSWei Yongjun 			goto exit;
1100170a39bSWei Yongjun 		}
1111bfd5294SAntti Palosaari 
1122b987ea7SAntti Palosaari 		dev_dbg(&intf->dev, "command=%02x failed fw error=%d\n",
1132b987ea7SAntti Palosaari 			req->cmd, state->buf[2]);
114786baecfSMauro Carvalho Chehab 		ret = -EIO;
1150170a39bSWei Yongjun 		goto exit;
116786baecfSMauro Carvalho Chehab 	}
117786baecfSMauro Carvalho Chehab 
118786baecfSMauro Carvalho Chehab 	/* read request, copy returned data to return buf */
119786baecfSMauro Carvalho Chehab 	if (req->rlen)
1203484d37aSAntti Palosaari 		memcpy(req->rbuf, &state->buf[ACK_HDR_LEN], req->rlen);
121786baecfSMauro Carvalho Chehab exit:
1223484d37aSAntti Palosaari 	mutex_unlock(&d->usb_mutex);
1230170a39bSWei Yongjun 	if (ret < 0)
1242b987ea7SAntti Palosaari 		dev_dbg(&intf->dev, "failed=%d\n", ret);
125786baecfSMauro Carvalho Chehab 	return ret;
126786baecfSMauro Carvalho Chehab }
127786baecfSMauro Carvalho Chehab 
128786baecfSMauro Carvalho Chehab /* write multiple registers */
129786baecfSMauro Carvalho Chehab static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
130786baecfSMauro Carvalho Chehab {
1312b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1327760e148SMauro Carvalho Chehab 	u8 wbuf[MAX_XFER_SIZE];
133786baecfSMauro Carvalho Chehab 	u8 mbox = (reg >> 16) & 0xff;
1349323297dSAntti Palosaari 	struct usb_req req = { CMD_MEM_WR, mbox, 6 + len, wbuf, 0, NULL };
135786baecfSMauro Carvalho Chehab 
1367760e148SMauro Carvalho Chehab 	if (6 + len > sizeof(wbuf)) {
1372b987ea7SAntti Palosaari 		dev_warn(&intf->dev, "i2c wr: len=%d is too big!\n", len);
1387760e148SMauro Carvalho Chehab 		return -EOPNOTSUPP;
1397760e148SMauro Carvalho Chehab 	}
1407760e148SMauro Carvalho Chehab 
141786baecfSMauro Carvalho Chehab 	wbuf[0] = len;
142786baecfSMauro Carvalho Chehab 	wbuf[1] = 2;
143786baecfSMauro Carvalho Chehab 	wbuf[2] = 0;
144786baecfSMauro Carvalho Chehab 	wbuf[3] = 0;
145786baecfSMauro Carvalho Chehab 	wbuf[4] = (reg >> 8) & 0xff;
146786baecfSMauro Carvalho Chehab 	wbuf[5] = (reg >> 0) & 0xff;
147786baecfSMauro Carvalho Chehab 	memcpy(&wbuf[6], val, len);
148786baecfSMauro Carvalho Chehab 
149786baecfSMauro Carvalho Chehab 	return af9035_ctrl_msg(d, &req);
150786baecfSMauro Carvalho Chehab }
151786baecfSMauro Carvalho Chehab 
152786baecfSMauro Carvalho Chehab /* read multiple registers */
153786baecfSMauro Carvalho Chehab static int af9035_rd_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
154786baecfSMauro Carvalho Chehab {
155786baecfSMauro Carvalho Chehab 	u8 wbuf[] = { len, 2, 0, 0, (reg >> 8) & 0xff, reg & 0xff };
156786baecfSMauro Carvalho Chehab 	u8 mbox = (reg >> 16) & 0xff;
157786baecfSMauro Carvalho Chehab 	struct usb_req req = { CMD_MEM_RD, mbox, sizeof(wbuf), wbuf, len, val };
158786baecfSMauro Carvalho Chehab 
159786baecfSMauro Carvalho Chehab 	return af9035_ctrl_msg(d, &req);
160786baecfSMauro Carvalho Chehab }
161786baecfSMauro Carvalho Chehab 
162786baecfSMauro Carvalho Chehab /* write single register */
163786baecfSMauro Carvalho Chehab static int af9035_wr_reg(struct dvb_usb_device *d, u32 reg, u8 val)
164786baecfSMauro Carvalho Chehab {
165786baecfSMauro Carvalho Chehab 	return af9035_wr_regs(d, reg, &val, 1);
166786baecfSMauro Carvalho Chehab }
167786baecfSMauro Carvalho Chehab 
168786baecfSMauro Carvalho Chehab /* read single register */
169786baecfSMauro Carvalho Chehab static int af9035_rd_reg(struct dvb_usb_device *d, u32 reg, u8 *val)
170786baecfSMauro Carvalho Chehab {
171786baecfSMauro Carvalho Chehab 	return af9035_rd_regs(d, reg, val, 1);
172786baecfSMauro Carvalho Chehab }
173786baecfSMauro Carvalho Chehab 
174786baecfSMauro Carvalho Chehab /* write single register with mask */
175786baecfSMauro Carvalho Chehab static int af9035_wr_reg_mask(struct dvb_usb_device *d, u32 reg, u8 val,
176786baecfSMauro Carvalho Chehab 		u8 mask)
177786baecfSMauro Carvalho Chehab {
178786baecfSMauro Carvalho Chehab 	int ret;
179786baecfSMauro Carvalho Chehab 	u8 tmp;
180786baecfSMauro Carvalho Chehab 
181786baecfSMauro Carvalho Chehab 	/* no need for read if whole reg is written */
182786baecfSMauro Carvalho Chehab 	if (mask != 0xff) {
183786baecfSMauro Carvalho Chehab 		ret = af9035_rd_regs(d, reg, &tmp, 1);
184786baecfSMauro Carvalho Chehab 		if (ret)
185786baecfSMauro Carvalho Chehab 			return ret;
186786baecfSMauro Carvalho Chehab 
187786baecfSMauro Carvalho Chehab 		val &= mask;
188786baecfSMauro Carvalho Chehab 		tmp &= ~mask;
189786baecfSMauro Carvalho Chehab 		val |= tmp;
190786baecfSMauro Carvalho Chehab 	}
191786baecfSMauro Carvalho Chehab 
192786baecfSMauro Carvalho Chehab 	return af9035_wr_regs(d, reg, &val, 1);
193786baecfSMauro Carvalho Chehab }
194786baecfSMauro Carvalho Chehab 
195a1ecf3c4SKees Cook static int af9035_add_i2c_dev(struct dvb_usb_device *d, const char *type,
196a1ecf3c4SKees Cook 		u8 addr, void *platform_data, struct i2c_adapter *adapter)
1973b2a5e8cSAntti Palosaari {
1983b2a5e8cSAntti Palosaari 	int ret, num;
1993b2a5e8cSAntti Palosaari 	struct state *state = d_to_priv(d);
2002b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
2013b2a5e8cSAntti Palosaari 	struct i2c_client *client;
2023b2a5e8cSAntti Palosaari 	struct i2c_board_info board_info = {
2033b2a5e8cSAntti Palosaari 		.addr = addr,
2043b2a5e8cSAntti Palosaari 		.platform_data = platform_data,
2053b2a5e8cSAntti Palosaari 	};
2063b2a5e8cSAntti Palosaari 
2073b2a5e8cSAntti Palosaari 	strlcpy(board_info.type, type, I2C_NAME_SIZE);
2083b2a5e8cSAntti Palosaari 
2093b2a5e8cSAntti Palosaari 	/* find first free client */
2103b2a5e8cSAntti Palosaari 	for (num = 0; num < AF9035_I2C_CLIENT_MAX; num++) {
2113b2a5e8cSAntti Palosaari 		if (state->i2c_client[num] == NULL)
2123b2a5e8cSAntti Palosaari 			break;
2133b2a5e8cSAntti Palosaari 	}
2143b2a5e8cSAntti Palosaari 
2152b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "num=%d\n", num);
2163b2a5e8cSAntti Palosaari 
2173b2a5e8cSAntti Palosaari 	if (num == AF9035_I2C_CLIENT_MAX) {
2182b987ea7SAntti Palosaari 		dev_err(&intf->dev, "I2C client out of index\n");
2193b2a5e8cSAntti Palosaari 		ret = -ENODEV;
2203b2a5e8cSAntti Palosaari 		goto err;
2213b2a5e8cSAntti Palosaari 	}
2223b2a5e8cSAntti Palosaari 
223a1ecf3c4SKees Cook 	request_module("%s", board_info.type);
2243b2a5e8cSAntti Palosaari 
2253b2a5e8cSAntti Palosaari 	/* register I2C device */
2263b2a5e8cSAntti Palosaari 	client = i2c_new_device(adapter, &board_info);
2273b2a5e8cSAntti Palosaari 	if (client == NULL || client->dev.driver == NULL) {
2283b2a5e8cSAntti Palosaari 		ret = -ENODEV;
2293b2a5e8cSAntti Palosaari 		goto err;
2303b2a5e8cSAntti Palosaari 	}
2313b2a5e8cSAntti Palosaari 
2323b2a5e8cSAntti Palosaari 	/* increase I2C driver usage count */
2333b2a5e8cSAntti Palosaari 	if (!try_module_get(client->dev.driver->owner)) {
2343b2a5e8cSAntti Palosaari 		i2c_unregister_device(client);
2353b2a5e8cSAntti Palosaari 		ret = -ENODEV;
2363b2a5e8cSAntti Palosaari 		goto err;
2373b2a5e8cSAntti Palosaari 	}
2383b2a5e8cSAntti Palosaari 
2393b2a5e8cSAntti Palosaari 	state->i2c_client[num] = client;
2403b2a5e8cSAntti Palosaari 	return 0;
2413b2a5e8cSAntti Palosaari err:
2422b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
2433b2a5e8cSAntti Palosaari 	return ret;
2443b2a5e8cSAntti Palosaari }
2453b2a5e8cSAntti Palosaari 
2463b2a5e8cSAntti Palosaari static void af9035_del_i2c_dev(struct dvb_usb_device *d)
2473b2a5e8cSAntti Palosaari {
2483b2a5e8cSAntti Palosaari 	int num;
2493b2a5e8cSAntti Palosaari 	struct state *state = d_to_priv(d);
2502b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
2513b2a5e8cSAntti Palosaari 	struct i2c_client *client;
2523b2a5e8cSAntti Palosaari 
2533b2a5e8cSAntti Palosaari 	/* find last used client */
2543b2a5e8cSAntti Palosaari 	num = AF9035_I2C_CLIENT_MAX;
2553b2a5e8cSAntti Palosaari 	while (num--) {
2563b2a5e8cSAntti Palosaari 		if (state->i2c_client[num] != NULL)
2573b2a5e8cSAntti Palosaari 			break;
2583b2a5e8cSAntti Palosaari 	}
2593b2a5e8cSAntti Palosaari 
2602b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "num=%d\n", num);
2613b2a5e8cSAntti Palosaari 
2623b2a5e8cSAntti Palosaari 	if (num == -1) {
2632b987ea7SAntti Palosaari 		dev_err(&intf->dev, "I2C client out of index\n");
2643b2a5e8cSAntti Palosaari 		goto err;
2653b2a5e8cSAntti Palosaari 	}
2663b2a5e8cSAntti Palosaari 
2673b2a5e8cSAntti Palosaari 	client = state->i2c_client[num];
2683b2a5e8cSAntti Palosaari 
2693b2a5e8cSAntti Palosaari 	/* decrease I2C driver usage count */
2703b2a5e8cSAntti Palosaari 	module_put(client->dev.driver->owner);
2713b2a5e8cSAntti Palosaari 
2723b2a5e8cSAntti Palosaari 	/* unregister I2C device */
2733b2a5e8cSAntti Palosaari 	i2c_unregister_device(client);
2743b2a5e8cSAntti Palosaari 
2753b2a5e8cSAntti Palosaari 	state->i2c_client[num] = NULL;
2763b2a5e8cSAntti Palosaari 	return;
2773b2a5e8cSAntti Palosaari err:
2782b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed\n");
2793b2a5e8cSAntti Palosaari }
2803b2a5e8cSAntti Palosaari 
281786baecfSMauro Carvalho Chehab static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
282786baecfSMauro Carvalho Chehab 		struct i2c_msg msg[], int num)
283786baecfSMauro Carvalho Chehab {
284786baecfSMauro Carvalho Chehab 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
285786baecfSMauro Carvalho Chehab 	struct state *state = d_to_priv(d);
286786baecfSMauro Carvalho Chehab 	int ret;
287786baecfSMauro Carvalho Chehab 
288786baecfSMauro Carvalho Chehab 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
289786baecfSMauro Carvalho Chehab 		return -EAGAIN;
290786baecfSMauro Carvalho Chehab 
291786baecfSMauro Carvalho Chehab 	/*
2925b556084SOlli Salonen 	 * AF9035 I2C sub header is 5 bytes long. Meaning of those bytes are:
293786baecfSMauro Carvalho Chehab 	 * 0: data len
294786baecfSMauro Carvalho Chehab 	 * 1: I2C addr << 1
295786baecfSMauro Carvalho Chehab 	 * 2: reg addr len
296786baecfSMauro Carvalho Chehab 	 *    byte 3 and 4 can be used as reg addr
297786baecfSMauro Carvalho Chehab 	 * 3: reg addr MSB
298786baecfSMauro Carvalho Chehab 	 *    used when reg addr len is set to 2
299786baecfSMauro Carvalho Chehab 	 * 4: reg addr LSB
300786baecfSMauro Carvalho Chehab 	 *    used when reg addr len is set to 1 or 2
301786baecfSMauro Carvalho Chehab 	 *
302786baecfSMauro Carvalho Chehab 	 * For the simplify we do not use register addr at all.
303786baecfSMauro Carvalho Chehab 	 * NOTE: As a firmware knows tuner type there is very small possibility
304786baecfSMauro Carvalho Chehab 	 * there could be some tuner I2C hacks done by firmware and this may
305786baecfSMauro Carvalho Chehab 	 * lead problems if firmware expects those bytes are used.
306f5b00a76SAntti Palosaari 	 *
307f5b00a76SAntti Palosaari 	 * TODO: Here is few hacks. AF9035 chip integrates AF9033 demodulator.
308f5b00a76SAntti Palosaari 	 * IT9135 chip integrates AF9033 demodulator and RF tuner. For dual
309f5b00a76SAntti Palosaari 	 * tuner devices, there is also external AF9033 demodulator connected
310f5b00a76SAntti Palosaari 	 * via external I2C bus. All AF9033 demod I2C traffic, both single and
311f5b00a76SAntti Palosaari 	 * dual tuner configuration, is covered by firmware - actual USB IO
312f5b00a76SAntti Palosaari 	 * looks just like a memory access.
313f5b00a76SAntti Palosaari 	 * In case of IT913x chip, there is own tuner driver. It is implemented
314f5b00a76SAntti Palosaari 	 * currently as a I2C driver, even tuner IP block is likely build
315f5b00a76SAntti Palosaari 	 * directly into the demodulator memory space and there is no own I2C
316f5b00a76SAntti Palosaari 	 * bus. I2C subsystem does not allow register multiple devices to same
317f5b00a76SAntti Palosaari 	 * bus, having same slave address. Due to that we reuse demod address,
318f5b00a76SAntti Palosaari 	 * shifted by one bit, on that case.
3195b556084SOlli Salonen 	 *
3205b556084SOlli Salonen 	 * For IT930x we use a different command and the sub header is
3215b556084SOlli Salonen 	 * different as well:
3225b556084SOlli Salonen 	 * 0: data len
3235b556084SOlli Salonen 	 * 1: I2C bus (0x03 seems to be only value used)
3245b556084SOlli Salonen 	 * 2: I2C addr << 1
325786baecfSMauro Carvalho Chehab 	 */
326ee36381eSAntti Palosaari #define AF9035_IS_I2C_XFER_WRITE_READ(_msg, _num) \
327ee36381eSAntti Palosaari 	(_num == 2 && !(_msg[0].flags & I2C_M_RD) && (_msg[1].flags & I2C_M_RD))
328ee36381eSAntti Palosaari #define AF9035_IS_I2C_XFER_WRITE(_msg, _num) \
329ee36381eSAntti Palosaari 	(_num == 1 && !(_msg[0].flags & I2C_M_RD))
330ee36381eSAntti Palosaari #define AF9035_IS_I2C_XFER_READ(_msg, _num) \
331ee36381eSAntti Palosaari 	(_num == 1 && (_msg[0].flags & I2C_M_RD))
332ee36381eSAntti Palosaari 
333ee36381eSAntti Palosaari 	if (AF9035_IS_I2C_XFER_WRITE_READ(msg, num)) {
334786baecfSMauro Carvalho Chehab 		if (msg[0].len > 40 || msg[1].len > 40) {
335786baecfSMauro Carvalho Chehab 			/* TODO: correct limits > 40 */
336786baecfSMauro Carvalho Chehab 			ret = -EOPNOTSUPP;
337a781edd1SAntti Palosaari 		} else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
338a781edd1SAntti Palosaari 			   (msg[0].addr == state->af9033_i2c_addr[1]) ||
339f5b00a76SAntti Palosaari 			   (state->chip_type == 0x9135)) {
340bf97b637SAntti Palosaari 			/* demod access via firmware interface */
341786baecfSMauro Carvalho Chehab 			u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
342786baecfSMauro Carvalho Chehab 					msg[0].buf[2];
343bf97b637SAntti Palosaari 
344a781edd1SAntti Palosaari 			if (msg[0].addr == state->af9033_i2c_addr[1] ||
345a781edd1SAntti Palosaari 			    msg[0].addr == (state->af9033_i2c_addr[1] >> 1))
3469805992fSJose Alberto Reguero 				reg |= 0x100000;
347bf97b637SAntti Palosaari 
348786baecfSMauro Carvalho Chehab 			ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
349786baecfSMauro Carvalho Chehab 					msg[1].len);
3501882f59fSAlessandro Radicati 		} else if (state->no_read) {
3511882f59fSAlessandro Radicati 			memset(msg[1].buf, 0, msg[1].len);
3521882f59fSAlessandro Radicati 			ret = 0;
353786baecfSMauro Carvalho Chehab 		} else {
354ee36381eSAntti Palosaari 			/* I2C write + read */
3557760e148SMauro Carvalho Chehab 			u8 buf[MAX_XFER_SIZE];
3569323297dSAntti Palosaari 			struct usb_req req = { CMD_I2C_RD, 0, 5 + msg[0].len,
357786baecfSMauro Carvalho Chehab 					buf, msg[1].len, msg[1].buf };
3587760e148SMauro Carvalho Chehab 
3595b556084SOlli Salonen 			if (state->chip_type == 0x9306) {
3605b556084SOlli Salonen 				req.cmd = CMD_GENERIC_I2C_RD;
3615b556084SOlli Salonen 				req.wlen = 3 + msg[0].len;
3625b556084SOlli Salonen 			}
3639805992fSJose Alberto Reguero 			req.mbox |= ((msg[0].addr & 0x80)  >>  3);
3645b556084SOlli Salonen 
365786baecfSMauro Carvalho Chehab 			buf[0] = msg[1].len;
3665b556084SOlli Salonen 			if (state->chip_type == 0x9306) {
3675b556084SOlli Salonen 				buf[1] = 0x03; /* I2C bus */
3685b556084SOlli Salonen 				buf[2] = msg[0].addr << 1;
3695b556084SOlli Salonen 				memcpy(&buf[3], msg[0].buf, msg[0].len);
3705b556084SOlli Salonen 			} else {
371bf97b637SAntti Palosaari 				buf[1] = msg[0].addr << 1;
372786baecfSMauro Carvalho Chehab 				buf[3] = 0x00; /* reg addr MSB */
373786baecfSMauro Carvalho Chehab 				buf[4] = 0x00; /* reg addr LSB */
37457f1c053SAlessandro Radicati 
37557f1c053SAlessandro Radicati 				/* Keep prev behavior for write req len > 2*/
37657f1c053SAlessandro Radicati 				if (msg[0].len > 2) {
37757f1c053SAlessandro Radicati 					buf[2] = 0x00; /* reg addr len */
378786baecfSMauro Carvalho Chehab 					memcpy(&buf[5], msg[0].buf, msg[0].len);
37957f1c053SAlessandro Radicati 
38057f1c053SAlessandro Radicati 				/* Use reg addr fields if write req len <= 2 */
38157f1c053SAlessandro Radicati 				} else {
38257f1c053SAlessandro Radicati 					req.wlen = 5;
38357f1c053SAlessandro Radicati 					buf[2] = msg[0].len;
38457f1c053SAlessandro Radicati 					if (msg[0].len == 2) {
38557f1c053SAlessandro Radicati 						buf[3] = msg[0].buf[0];
38657f1c053SAlessandro Radicati 						buf[4] = msg[0].buf[1];
38757f1c053SAlessandro Radicati 					} else if (msg[0].len == 1) {
38857f1c053SAlessandro Radicati 						buf[4] = msg[0].buf[0];
38957f1c053SAlessandro Radicati 					}
39057f1c053SAlessandro Radicati 				}
3915b556084SOlli Salonen 			}
392786baecfSMauro Carvalho Chehab 			ret = af9035_ctrl_msg(d, &req);
393786baecfSMauro Carvalho Chehab 		}
394ee36381eSAntti Palosaari 	} else if (AF9035_IS_I2C_XFER_WRITE(msg, num)) {
395786baecfSMauro Carvalho Chehab 		if (msg[0].len > 40) {
396786baecfSMauro Carvalho Chehab 			/* TODO: correct limits > 40 */
397786baecfSMauro Carvalho Chehab 			ret = -EOPNOTSUPP;
398a781edd1SAntti Palosaari 		} else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
399a781edd1SAntti Palosaari 			   (msg[0].addr == state->af9033_i2c_addr[1]) ||
400f5b00a76SAntti Palosaari 			   (state->chip_type == 0x9135)) {
401bf97b637SAntti Palosaari 			/* demod access via firmware interface */
402786baecfSMauro Carvalho Chehab 			u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
403786baecfSMauro Carvalho Chehab 					msg[0].buf[2];
404bf97b637SAntti Palosaari 
405a781edd1SAntti Palosaari 			if (msg[0].addr == state->af9033_i2c_addr[1] ||
406a781edd1SAntti Palosaari 			    msg[0].addr == (state->af9033_i2c_addr[1] >> 1))
4079805992fSJose Alberto Reguero 				reg |= 0x100000;
408bf97b637SAntti Palosaari 
409786baecfSMauro Carvalho Chehab 			ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
410786baecfSMauro Carvalho Chehab 					msg[0].len - 3);
411786baecfSMauro Carvalho Chehab 		} else {
412ee36381eSAntti Palosaari 			/* I2C write */
4137760e148SMauro Carvalho Chehab 			u8 buf[MAX_XFER_SIZE];
4149323297dSAntti Palosaari 			struct usb_req req = { CMD_I2C_WR, 0, 5 + msg[0].len,
4159323297dSAntti Palosaari 					buf, 0, NULL };
4167760e148SMauro Carvalho Chehab 
4175b556084SOlli Salonen 			if (state->chip_type == 0x9306) {
4185b556084SOlli Salonen 				req.cmd = CMD_GENERIC_I2C_WR;
4195b556084SOlli Salonen 				req.wlen = 3 + msg[0].len;
4205b556084SOlli Salonen 			}
4215b556084SOlli Salonen 
4229805992fSJose Alberto Reguero 			req.mbox |= ((msg[0].addr & 0x80)  >>  3);
423786baecfSMauro Carvalho Chehab 			buf[0] = msg[0].len;
4245b556084SOlli Salonen 			if (state->chip_type == 0x9306) {
4255b556084SOlli Salonen 				buf[1] = 0x03; /* I2C bus */
4265b556084SOlli Salonen 				buf[2] = msg[0].addr << 1;
4275b556084SOlli Salonen 				memcpy(&buf[3], msg[0].buf, msg[0].len);
4285b556084SOlli Salonen 			} else {
429bf97b637SAntti Palosaari 				buf[1] = msg[0].addr << 1;
430786baecfSMauro Carvalho Chehab 				buf[2] = 0x00; /* reg addr len */
431786baecfSMauro Carvalho Chehab 				buf[3] = 0x00; /* reg addr MSB */
432786baecfSMauro Carvalho Chehab 				buf[4] = 0x00; /* reg addr LSB */
433786baecfSMauro Carvalho Chehab 				memcpy(&buf[5], msg[0].buf, msg[0].len);
4345b556084SOlli Salonen 			}
435786baecfSMauro Carvalho Chehab 			ret = af9035_ctrl_msg(d, &req);
436786baecfSMauro Carvalho Chehab 		}
437ee36381eSAntti Palosaari 	} else if (AF9035_IS_I2C_XFER_READ(msg, num)) {
4383b98c347SAntti Palosaari 		if (msg[0].len > 40) {
4393b98c347SAntti Palosaari 			/* TODO: correct limits > 40 */
4403b98c347SAntti Palosaari 			ret = -EOPNOTSUPP;
4411882f59fSAlessandro Radicati 		} else if (state->no_read) {
4421882f59fSAlessandro Radicati 			memset(msg[0].buf, 0, msg[0].len);
4431882f59fSAlessandro Radicati 			ret = 0;
4443b98c347SAntti Palosaari 		} else {
445ee36381eSAntti Palosaari 			/* I2C read */
4463b98c347SAntti Palosaari 			u8 buf[5];
4473b98c347SAntti Palosaari 			struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
4483b98c347SAntti Palosaari 						buf, msg[0].len, msg[0].buf };
4495b556084SOlli Salonen 
4505b556084SOlli Salonen 			if (state->chip_type == 0x9306) {
4515b556084SOlli Salonen 				req.cmd = CMD_GENERIC_I2C_RD;
4525b556084SOlli Salonen 				req.wlen = 3;
4535b556084SOlli Salonen 			}
4543b98c347SAntti Palosaari 			req.mbox |= ((msg[0].addr & 0x80)  >>  3);
4553b98c347SAntti Palosaari 			buf[0] = msg[0].len;
4565b556084SOlli Salonen 			if (state->chip_type == 0x9306) {
4575b556084SOlli Salonen 				buf[1] = 0x03; /* I2C bus */
4585b556084SOlli Salonen 				buf[2] = msg[0].addr << 1;
4595b556084SOlli Salonen 			} else {
4603b98c347SAntti Palosaari 				buf[1] = msg[0].addr << 1;
4613b98c347SAntti Palosaari 				buf[2] = 0x00; /* reg addr len */
4623b98c347SAntti Palosaari 				buf[3] = 0x00; /* reg addr MSB */
4633b98c347SAntti Palosaari 				buf[4] = 0x00; /* reg addr LSB */
4645b556084SOlli Salonen 			}
4653b98c347SAntti Palosaari 			ret = af9035_ctrl_msg(d, &req);
4663b98c347SAntti Palosaari 		}
467786baecfSMauro Carvalho Chehab 	} else {
468786baecfSMauro Carvalho Chehab 		/*
4693b98c347SAntti Palosaari 		 * We support only three kind of I2C transactions:
470ee36381eSAntti Palosaari 		 * 1) 1 x write + 1 x read (repeated start)
471786baecfSMauro Carvalho Chehab 		 * 2) 1 x write
4723b98c347SAntti Palosaari 		 * 3) 1 x read
473786baecfSMauro Carvalho Chehab 		 */
474786baecfSMauro Carvalho Chehab 		ret = -EOPNOTSUPP;
475786baecfSMauro Carvalho Chehab 	}
476786baecfSMauro Carvalho Chehab 
477786baecfSMauro Carvalho Chehab 	mutex_unlock(&d->i2c_mutex);
478786baecfSMauro Carvalho Chehab 
479786baecfSMauro Carvalho Chehab 	if (ret < 0)
480786baecfSMauro Carvalho Chehab 		return ret;
481786baecfSMauro Carvalho Chehab 	else
482786baecfSMauro Carvalho Chehab 		return num;
483786baecfSMauro Carvalho Chehab }
484786baecfSMauro Carvalho Chehab 
485786baecfSMauro Carvalho Chehab static u32 af9035_i2c_functionality(struct i2c_adapter *adapter)
486786baecfSMauro Carvalho Chehab {
487786baecfSMauro Carvalho Chehab 	return I2C_FUNC_I2C;
488786baecfSMauro Carvalho Chehab }
489786baecfSMauro Carvalho Chehab 
490786baecfSMauro Carvalho Chehab static struct i2c_algorithm af9035_i2c_algo = {
491786baecfSMauro Carvalho Chehab 	.master_xfer = af9035_i2c_master_xfer,
492786baecfSMauro Carvalho Chehab 	.functionality = af9035_i2c_functionality,
493786baecfSMauro Carvalho Chehab };
494786baecfSMauro Carvalho Chehab 
495786baecfSMauro Carvalho Chehab static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
496786baecfSMauro Carvalho Chehab {
49774c1883aSAntti Palosaari 	struct state *state = d_to_priv(d);
4982b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
49909bfd96cSAntti Palosaari 	int ret, i, ts_mode_invalid;
50009bfd96cSAntti Palosaari 	unsigned int utmp, eeprom_addr;
5019e422f64SStefan Pöschel 	u8 tmp;
502786baecfSMauro Carvalho Chehab 	u8 wbuf[1] = { 1 };
503786baecfSMauro Carvalho Chehab 	u8 rbuf[4];
504786baecfSMauro Carvalho Chehab 	struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf,
505786baecfSMauro Carvalho Chehab 			sizeof(rbuf), rbuf };
506786baecfSMauro Carvalho Chehab 
50774c1883aSAntti Palosaari 	ret = af9035_rd_regs(d, 0x1222, rbuf, 3);
50874c1883aSAntti Palosaari 	if (ret < 0)
50974c1883aSAntti Palosaari 		goto err;
51074c1883aSAntti Palosaari 
51174c1883aSAntti Palosaari 	state->chip_version = rbuf[0];
51274c1883aSAntti Palosaari 	state->chip_type = rbuf[2] << 8 | rbuf[1] << 0;
51374c1883aSAntti Palosaari 
51474c1883aSAntti Palosaari 	ret = af9035_rd_reg(d, 0x384f, &state->prechip_version);
51574c1883aSAntti Palosaari 	if (ret < 0)
51674c1883aSAntti Palosaari 		goto err;
51774c1883aSAntti Palosaari 
5182b987ea7SAntti Palosaari 	dev_info(&intf->dev, "prechip_version=%02x chip_version=%02x chip_type=%04x\n",
5192b987ea7SAntti Palosaari 		 state->prechip_version, state->chip_version, state->chip_type);
52074c1883aSAntti Palosaari 
52174c1883aSAntti Palosaari 	if (state->chip_type == 0x9135) {
52209bfd96cSAntti Palosaari 		if (state->chip_version == 0x02) {
52374c1883aSAntti Palosaari 			*name = AF9035_FIRMWARE_IT9135_V2;
52409bfd96cSAntti Palosaari 			utmp = 0x00461d;
52574c1883aSAntti Palosaari 		} else {
52609bfd96cSAntti Palosaari 			*name = AF9035_FIRMWARE_IT9135_V1;
52709bfd96cSAntti Palosaari 			utmp = 0x00461b;
52874c1883aSAntti Palosaari 		}
52974c1883aSAntti Palosaari 
53009bfd96cSAntti Palosaari 		/* Check if eeprom exists */
53109bfd96cSAntti Palosaari 		ret = af9035_rd_reg(d, utmp, &tmp);
5329e422f64SStefan Pöschel 		if (ret < 0)
5339e422f64SStefan Pöschel 			goto err;
5349e422f64SStefan Pöschel 
53509bfd96cSAntti Palosaari 		if (tmp == 0x00) {
53609bfd96cSAntti Palosaari 			dev_dbg(&intf->dev, "no eeprom\n");
53709bfd96cSAntti Palosaari 			state->no_eeprom = true;
53809bfd96cSAntti Palosaari 			goto check_firmware_status;
53909bfd96cSAntti Palosaari 		}
54009bfd96cSAntti Palosaari 
54109bfd96cSAntti Palosaari 		eeprom_addr = EEPROM_BASE_IT9135;
54209bfd96cSAntti Palosaari 	} else if (state->chip_type == 0x9306) {
54309bfd96cSAntti Palosaari 		*name = AF9035_FIRMWARE_IT9303;
54409bfd96cSAntti Palosaari 		state->no_eeprom = true;
54509bfd96cSAntti Palosaari 		goto check_firmware_status;
54609bfd96cSAntti Palosaari 	} else {
54709bfd96cSAntti Palosaari 		*name = AF9035_FIRMWARE_AF9035;
54809bfd96cSAntti Palosaari 		eeprom_addr = EEPROM_BASE_AF9035;
54909bfd96cSAntti Palosaari 	}
55009bfd96cSAntti Palosaari 
55109bfd96cSAntti Palosaari 	/* Read and store eeprom */
55209bfd96cSAntti Palosaari 	for (i = 0; i < 256; i += 32) {
55309bfd96cSAntti Palosaari 		ret = af9035_rd_regs(d, eeprom_addr + i, &state->eeprom[i], 32);
55409bfd96cSAntti Palosaari 		if (ret < 0)
55509bfd96cSAntti Palosaari 			goto err;
55609bfd96cSAntti Palosaari 	}
55709bfd96cSAntti Palosaari 
55809bfd96cSAntti Palosaari 	dev_dbg(&intf->dev, "eeprom dump:\n");
55909bfd96cSAntti Palosaari 	for (i = 0; i < 256; i += 16)
56009bfd96cSAntti Palosaari 		dev_dbg(&intf->dev, "%*ph\n", 16, &state->eeprom[i]);
56109bfd96cSAntti Palosaari 
56209bfd96cSAntti Palosaari 	/* check for dual tuner mode */
56309bfd96cSAntti Palosaari 	tmp = state->eeprom[EEPROM_TS_MODE];
5649e422f64SStefan Pöschel 	ts_mode_invalid = 0;
5659e422f64SStefan Pöschel 	switch (tmp) {
5669e422f64SStefan Pöschel 	case 0:
5679e422f64SStefan Pöschel 		break;
5689e422f64SStefan Pöschel 	case 1:
5699e422f64SStefan Pöschel 	case 3:
5709e422f64SStefan Pöschel 		state->dual_mode = true;
5719e422f64SStefan Pöschel 		break;
5729e422f64SStefan Pöschel 	case 5:
5739e422f64SStefan Pöschel 		if (state->chip_type != 0x9135 && state->chip_type != 0x9306)
5749e422f64SStefan Pöschel 			state->dual_mode = true;	/* AF9035 */
5759e422f64SStefan Pöschel 		else
5769e422f64SStefan Pöschel 			ts_mode_invalid = 1;
5779e422f64SStefan Pöschel 		break;
5789e422f64SStefan Pöschel 	default:
5799e422f64SStefan Pöschel 		ts_mode_invalid = 1;
5809e422f64SStefan Pöschel 	}
5819e422f64SStefan Pöschel 
5829e422f64SStefan Pöschel 	dev_dbg(&intf->dev, "ts mode=%d dual mode=%d\n", tmp, state->dual_mode);
5839e422f64SStefan Pöschel 
5849e422f64SStefan Pöschel 	if (ts_mode_invalid)
5859e422f64SStefan Pöschel 		dev_info(&intf->dev, "ts mode=%d not supported, defaulting to single tuner mode!", tmp);
5869e422f64SStefan Pöschel 
58709bfd96cSAntti Palosaari check_firmware_status:
588786baecfSMauro Carvalho Chehab 	ret = af9035_ctrl_msg(d, &req);
589786baecfSMauro Carvalho Chehab 	if (ret < 0)
590786baecfSMauro Carvalho Chehab 		goto err;
591786baecfSMauro Carvalho Chehab 
5922b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "reply=%*ph\n", 4, rbuf);
593786baecfSMauro Carvalho Chehab 	if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])
594786baecfSMauro Carvalho Chehab 		ret = WARM;
595786baecfSMauro Carvalho Chehab 	else
596786baecfSMauro Carvalho Chehab 		ret = COLD;
597786baecfSMauro Carvalho Chehab 
598786baecfSMauro Carvalho Chehab 	return ret;
599786baecfSMauro Carvalho Chehab 
600786baecfSMauro Carvalho Chehab err:
6012b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
602786baecfSMauro Carvalho Chehab 
603786baecfSMauro Carvalho Chehab 	return ret;
604786baecfSMauro Carvalho Chehab }
605786baecfSMauro Carvalho Chehab 
6068229da50SAntti Palosaari static int af9035_download_firmware_old(struct dvb_usb_device *d,
607786baecfSMauro Carvalho Chehab 		const struct firmware *fw)
608786baecfSMauro Carvalho Chehab {
6092b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
610786baecfSMauro Carvalho Chehab 	int ret, i, j, len;
611786baecfSMauro Carvalho Chehab 	u8 wbuf[1];
612786baecfSMauro Carvalho Chehab 	struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
613786baecfSMauro Carvalho Chehab 	struct usb_req req_fw_dl = { CMD_FW_DL, 0, 0, wbuf, 0, NULL };
614df8f1be1SAntti Palosaari 	u8 hdr_core;
615786baecfSMauro Carvalho Chehab 	u16 hdr_addr, hdr_data_len, hdr_checksum;
616786baecfSMauro Carvalho Chehab 	#define MAX_DATA 58
617786baecfSMauro Carvalho Chehab 	#define HDR_SIZE 7
618786baecfSMauro Carvalho Chehab 
619786baecfSMauro Carvalho Chehab 	/*
620786baecfSMauro Carvalho Chehab 	 * Thanks to Daniel Glöckner <daniel-gl@gmx.net> about that info!
621786baecfSMauro Carvalho Chehab 	 *
622786baecfSMauro Carvalho Chehab 	 * byte 0: MCS 51 core
623786baecfSMauro Carvalho Chehab 	 *  There are two inside the AF9035 (1=Link and 2=OFDM) with separate
624786baecfSMauro Carvalho Chehab 	 *  address spaces
625786baecfSMauro Carvalho Chehab 	 * byte 1-2: Big endian destination address
626786baecfSMauro Carvalho Chehab 	 * byte 3-4: Big endian number of data bytes following the header
627786baecfSMauro Carvalho Chehab 	 * byte 5-6: Big endian header checksum, apparently ignored by the chip
628786baecfSMauro Carvalho Chehab 	 *  Calculated as ~(h[0]*256+h[1]+h[2]*256+h[3]+h[4]*256)
629786baecfSMauro Carvalho Chehab 	 */
630786baecfSMauro Carvalho Chehab 
631786baecfSMauro Carvalho Chehab 	for (i = fw->size; i > HDR_SIZE;) {
632786baecfSMauro Carvalho Chehab 		hdr_core = fw->data[fw->size - i + 0];
633786baecfSMauro Carvalho Chehab 		hdr_addr = fw->data[fw->size - i + 1] << 8;
634786baecfSMauro Carvalho Chehab 		hdr_addr |= fw->data[fw->size - i + 2] << 0;
635786baecfSMauro Carvalho Chehab 		hdr_data_len = fw->data[fw->size - i + 3] << 8;
636786baecfSMauro Carvalho Chehab 		hdr_data_len |= fw->data[fw->size - i + 4] << 0;
637786baecfSMauro Carvalho Chehab 		hdr_checksum = fw->data[fw->size - i + 5] << 8;
638786baecfSMauro Carvalho Chehab 		hdr_checksum |= fw->data[fw->size - i + 6] << 0;
639786baecfSMauro Carvalho Chehab 
6402b987ea7SAntti Palosaari 		dev_dbg(&intf->dev, "core=%d addr=%04x data_len=%d checksum=%04x\n",
6412b987ea7SAntti Palosaari 			hdr_core, hdr_addr, hdr_data_len, hdr_checksum);
642786baecfSMauro Carvalho Chehab 
643786baecfSMauro Carvalho Chehab 		if (((hdr_core != 1) && (hdr_core != 2)) ||
644786baecfSMauro Carvalho Chehab 				(hdr_data_len > i)) {
6452b987ea7SAntti Palosaari 			dev_dbg(&intf->dev, "bad firmware\n");
646786baecfSMauro Carvalho Chehab 			break;
647786baecfSMauro Carvalho Chehab 		}
648786baecfSMauro Carvalho Chehab 
649786baecfSMauro Carvalho Chehab 		/* download begin packet */
650786baecfSMauro Carvalho Chehab 		req.cmd = CMD_FW_DL_BEGIN;
651786baecfSMauro Carvalho Chehab 		ret = af9035_ctrl_msg(d, &req);
652786baecfSMauro Carvalho Chehab 		if (ret < 0)
653786baecfSMauro Carvalho Chehab 			goto err;
654786baecfSMauro Carvalho Chehab 
655786baecfSMauro Carvalho Chehab 		/* download firmware packet(s) */
656786baecfSMauro Carvalho Chehab 		for (j = HDR_SIZE + hdr_data_len; j > 0; j -= MAX_DATA) {
657786baecfSMauro Carvalho Chehab 			len = j;
658786baecfSMauro Carvalho Chehab 			if (len > MAX_DATA)
659786baecfSMauro Carvalho Chehab 				len = MAX_DATA;
660786baecfSMauro Carvalho Chehab 			req_fw_dl.wlen = len;
661786baecfSMauro Carvalho Chehab 			req_fw_dl.wbuf = (u8 *) &fw->data[fw->size - i +
662786baecfSMauro Carvalho Chehab 					HDR_SIZE + hdr_data_len - j];
663786baecfSMauro Carvalho Chehab 			ret = af9035_ctrl_msg(d, &req_fw_dl);
664786baecfSMauro Carvalho Chehab 			if (ret < 0)
665786baecfSMauro Carvalho Chehab 				goto err;
666786baecfSMauro Carvalho Chehab 		}
667786baecfSMauro Carvalho Chehab 
668786baecfSMauro Carvalho Chehab 		/* download end packet */
669786baecfSMauro Carvalho Chehab 		req.cmd = CMD_FW_DL_END;
670786baecfSMauro Carvalho Chehab 		ret = af9035_ctrl_msg(d, &req);
671786baecfSMauro Carvalho Chehab 		if (ret < 0)
672786baecfSMauro Carvalho Chehab 			goto err;
673786baecfSMauro Carvalho Chehab 
674786baecfSMauro Carvalho Chehab 		i -= hdr_data_len + HDR_SIZE;
675786baecfSMauro Carvalho Chehab 
6762b987ea7SAntti Palosaari 		dev_dbg(&intf->dev, "data uploaded=%zu\n", fw->size - i);
677786baecfSMauro Carvalho Chehab 	}
678786baecfSMauro Carvalho Chehab 
679ff4e3fe8SAntti Palosaari 	/* print warn if firmware is bad, continue and see what happens */
680ff4e3fe8SAntti Palosaari 	if (i)
6812b987ea7SAntti Palosaari 		dev_warn(&intf->dev, "bad firmware\n");
682ff4e3fe8SAntti Palosaari 
683786baecfSMauro Carvalho Chehab 	return 0;
684786baecfSMauro Carvalho Chehab 
685786baecfSMauro Carvalho Chehab err:
6862b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
687786baecfSMauro Carvalho Chehab 
688786baecfSMauro Carvalho Chehab 	return ret;
689786baecfSMauro Carvalho Chehab }
690786baecfSMauro Carvalho Chehab 
6918229da50SAntti Palosaari static int af9035_download_firmware_new(struct dvb_usb_device *d,
692786baecfSMauro Carvalho Chehab 		const struct firmware *fw)
693786baecfSMauro Carvalho Chehab {
6942b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
695786baecfSMauro Carvalho Chehab 	int ret, i, i_prev;
696786baecfSMauro Carvalho Chehab 	struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL };
697786baecfSMauro Carvalho Chehab 	#define HDR_SIZE 7
698786baecfSMauro Carvalho Chehab 
699786baecfSMauro Carvalho Chehab 	/*
700786baecfSMauro Carvalho Chehab 	 * There seems to be following firmware header. Meaning of bytes 0-3
701786baecfSMauro Carvalho Chehab 	 * is unknown.
702786baecfSMauro Carvalho Chehab 	 *
703786baecfSMauro Carvalho Chehab 	 * 0: 3
704786baecfSMauro Carvalho Chehab 	 * 1: 0, 1
705786baecfSMauro Carvalho Chehab 	 * 2: 0
706786baecfSMauro Carvalho Chehab 	 * 3: 1, 2, 3
707786baecfSMauro Carvalho Chehab 	 * 4: addr MSB
708786baecfSMauro Carvalho Chehab 	 * 5: addr LSB
709786baecfSMauro Carvalho Chehab 	 * 6: count of data bytes ?
710786baecfSMauro Carvalho Chehab 	 */
711786baecfSMauro Carvalho Chehab 	for (i = HDR_SIZE, i_prev = 0; i <= fw->size; i++) {
712786baecfSMauro Carvalho Chehab 		if (i == fw->size ||
713786baecfSMauro Carvalho Chehab 				(fw->data[i + 0] == 0x03 &&
714786baecfSMauro Carvalho Chehab 				(fw->data[i + 1] == 0x00 ||
715786baecfSMauro Carvalho Chehab 				fw->data[i + 1] == 0x01) &&
716786baecfSMauro Carvalho Chehab 				fw->data[i + 2] == 0x00)) {
717786baecfSMauro Carvalho Chehab 			req_fw_dl.wlen = i - i_prev;
718786baecfSMauro Carvalho Chehab 			req_fw_dl.wbuf = (u8 *) &fw->data[i_prev];
719786baecfSMauro Carvalho Chehab 			i_prev = i;
720786baecfSMauro Carvalho Chehab 			ret = af9035_ctrl_msg(d, &req_fw_dl);
721786baecfSMauro Carvalho Chehab 			if (ret < 0)
722786baecfSMauro Carvalho Chehab 				goto err;
723786baecfSMauro Carvalho Chehab 
7242b987ea7SAntti Palosaari 			dev_dbg(&intf->dev, "data uploaded=%d\n", i);
725786baecfSMauro Carvalho Chehab 		}
726786baecfSMauro Carvalho Chehab 	}
727786baecfSMauro Carvalho Chehab 
728df8f1be1SAntti Palosaari 	return 0;
729df8f1be1SAntti Palosaari 
730df8f1be1SAntti Palosaari err:
7312b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
732df8f1be1SAntti Palosaari 
733df8f1be1SAntti Palosaari 	return ret;
734df8f1be1SAntti Palosaari }
735df8f1be1SAntti Palosaari 
736df8f1be1SAntti Palosaari static int af9035_download_firmware(struct dvb_usb_device *d,
737df8f1be1SAntti Palosaari 		const struct firmware *fw)
738df8f1be1SAntti Palosaari {
7392b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
740df8f1be1SAntti Palosaari 	struct state *state = d_to_priv(d);
741df8f1be1SAntti Palosaari 	int ret;
742df8f1be1SAntti Palosaari 	u8 wbuf[1];
743df8f1be1SAntti Palosaari 	u8 rbuf[4];
744df8f1be1SAntti Palosaari 	u8 tmp;
745df8f1be1SAntti Palosaari 	struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
746df8f1be1SAntti Palosaari 	struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf };
747c10989a2SAntti Palosaari 
7482b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "\n");
749df8f1be1SAntti Palosaari 
750df8f1be1SAntti Palosaari 	/*
751df8f1be1SAntti Palosaari 	 * In case of dual tuner configuration we need to do some extra
752df8f1be1SAntti Palosaari 	 * initialization in order to download firmware to slave demod too,
753df8f1be1SAntti Palosaari 	 * which is done by master demod.
754df8f1be1SAntti Palosaari 	 * Master feeds also clock and controls power via GPIO.
755df8f1be1SAntti Palosaari 	 */
7569e422f64SStefan Pöschel 	if (state->dual_mode) {
757df8f1be1SAntti Palosaari 		/* configure gpioh1, reset & power slave demod */
758df8f1be1SAntti Palosaari 		ret = af9035_wr_reg_mask(d, 0x00d8b0, 0x01, 0x01);
759df8f1be1SAntti Palosaari 		if (ret < 0)
760df8f1be1SAntti Palosaari 			goto err;
761df8f1be1SAntti Palosaari 
762df8f1be1SAntti Palosaari 		ret = af9035_wr_reg_mask(d, 0x00d8b1, 0x01, 0x01);
763df8f1be1SAntti Palosaari 		if (ret < 0)
764df8f1be1SAntti Palosaari 			goto err;
765df8f1be1SAntti Palosaari 
766df8f1be1SAntti Palosaari 		ret = af9035_wr_reg_mask(d, 0x00d8af, 0x00, 0x01);
767df8f1be1SAntti Palosaari 		if (ret < 0)
768df8f1be1SAntti Palosaari 			goto err;
769df8f1be1SAntti Palosaari 
770df8f1be1SAntti Palosaari 		usleep_range(10000, 50000);
771df8f1be1SAntti Palosaari 
772df8f1be1SAntti Palosaari 		ret = af9035_wr_reg_mask(d, 0x00d8af, 0x01, 0x01);
773df8f1be1SAntti Palosaari 		if (ret < 0)
774df8f1be1SAntti Palosaari 			goto err;
775df8f1be1SAntti Palosaari 
776df8f1be1SAntti Palosaari 		/* tell the slave I2C address */
77709bfd96cSAntti Palosaari 		tmp = state->eeprom[EEPROM_2ND_DEMOD_ADDR];
778df8f1be1SAntti Palosaari 
77914992f01SAntti Palosaari 		/* use default I2C address if eeprom has no address set */
780a1310ff4SMalcolm Priestley 		if (!tmp)
781a1310ff4SMalcolm Priestley 			tmp = 0x3a;
782a1310ff4SMalcolm Priestley 
7835b556084SOlli Salonen 		if ((state->chip_type == 0x9135) ||
7845b556084SOlli Salonen 				(state->chip_type == 0x9306)) {
785df8f1be1SAntti Palosaari 			ret = af9035_wr_reg(d, 0x004bfb, tmp);
786df8f1be1SAntti Palosaari 			if (ret < 0)
787df8f1be1SAntti Palosaari 				goto err;
788df8f1be1SAntti Palosaari 		} else {
789df8f1be1SAntti Palosaari 			ret = af9035_wr_reg(d, 0x00417f, tmp);
790df8f1be1SAntti Palosaari 			if (ret < 0)
791df8f1be1SAntti Palosaari 				goto err;
792df8f1be1SAntti Palosaari 
793df8f1be1SAntti Palosaari 			/* enable clock out */
794df8f1be1SAntti Palosaari 			ret = af9035_wr_reg_mask(d, 0x00d81a, 0x01, 0x01);
795df8f1be1SAntti Palosaari 			if (ret < 0)
796df8f1be1SAntti Palosaari 				goto err;
797df8f1be1SAntti Palosaari 		}
798df8f1be1SAntti Palosaari 	}
799df8f1be1SAntti Palosaari 
8008229da50SAntti Palosaari 	if (fw->data[0] == 0x01)
8018229da50SAntti Palosaari 		ret = af9035_download_firmware_old(d, fw);
802df8f1be1SAntti Palosaari 	else
8038229da50SAntti Palosaari 		ret = af9035_download_firmware_new(d, fw);
804df8f1be1SAntti Palosaari 	if (ret < 0)
805df8f1be1SAntti Palosaari 		goto err;
806df8f1be1SAntti Palosaari 
807786baecfSMauro Carvalho Chehab 	/* firmware loaded, request boot */
808786baecfSMauro Carvalho Chehab 	req.cmd = CMD_FW_BOOT;
809786baecfSMauro Carvalho Chehab 	ret = af9035_ctrl_msg(d, &req);
810786baecfSMauro Carvalho Chehab 	if (ret < 0)
811786baecfSMauro Carvalho Chehab 		goto err;
812786baecfSMauro Carvalho Chehab 
813786baecfSMauro Carvalho Chehab 	/* ensure firmware starts */
814786baecfSMauro Carvalho Chehab 	wbuf[0] = 1;
815786baecfSMauro Carvalho Chehab 	ret = af9035_ctrl_msg(d, &req_fw_ver);
816786baecfSMauro Carvalho Chehab 	if (ret < 0)
817786baecfSMauro Carvalho Chehab 		goto err;
818786baecfSMauro Carvalho Chehab 
819786baecfSMauro Carvalho Chehab 	if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
8202b987ea7SAntti Palosaari 		dev_err(&intf->dev, "firmware did not run\n");
821786baecfSMauro Carvalho Chehab 		ret = -ENODEV;
822786baecfSMauro Carvalho Chehab 		goto err;
823786baecfSMauro Carvalho Chehab 	}
824786baecfSMauro Carvalho Chehab 
8252b987ea7SAntti Palosaari 	dev_info(&intf->dev, "firmware version=%d.%d.%d.%d",
8262b987ea7SAntti Palosaari 		 rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
827786baecfSMauro Carvalho Chehab 
828786baecfSMauro Carvalho Chehab 	return 0;
829786baecfSMauro Carvalho Chehab 
830786baecfSMauro Carvalho Chehab err:
8312b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
832786baecfSMauro Carvalho Chehab 
833786baecfSMauro Carvalho Chehab 	return ret;
834786baecfSMauro Carvalho Chehab }
835786baecfSMauro Carvalho Chehab 
8369ea3681dSAntti Palosaari static int af9035_read_config(struct dvb_usb_device *d)
837786baecfSMauro Carvalho Chehab {
8382b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
839786baecfSMauro Carvalho Chehab 	struct state *state = d_to_priv(d);
8409ea3681dSAntti Palosaari 	int ret, i;
841786baecfSMauro Carvalho Chehab 	u8 tmp;
84209bfd96cSAntti Palosaari 	u16 tmp16;
843786baecfSMauro Carvalho Chehab 
844bf97b637SAntti Palosaari 	/* demod I2C "address" */
845a781edd1SAntti Palosaari 	state->af9033_i2c_addr[0] = 0x38;
846a781edd1SAntti Palosaari 	state->af9033_i2c_addr[1] = 0x3a;
8470d94d6a0SAntti Palosaari 	state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X;
848df8f1be1SAntti Palosaari 	state->af9033_config[1].adc_multiplier = AF9033_ADC_MULTIPLIER_2X;
849ab56ad6aSAntti Palosaari 	state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
850ab56ad6aSAntti Palosaari 	state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL;
851bf97b637SAntti Palosaari 
8529ea3681dSAntti Palosaari 	if (state->chip_type == 0x9135) {
85315ba8202SAntti Palosaari 		/* feed clock for integrated RF tuner */
85415ba8202SAntti Palosaari 		state->af9033_config[0].dyn0_clk = true;
85515ba8202SAntti Palosaari 		state->af9033_config[1].dyn0_clk = true;
85615ba8202SAntti Palosaari 
857bc3c9e10SAntti Palosaari 		if (state->chip_version == 0x02) {
858bc3c9e10SAntti Palosaari 			state->af9033_config[0].tuner = AF9033_TUNER_IT9135_60;
859df8f1be1SAntti Palosaari 			state->af9033_config[1].tuner = AF9033_TUNER_IT9135_60;
860bc3c9e10SAntti Palosaari 		} else {
861bc3c9e10SAntti Palosaari 			state->af9033_config[0].tuner = AF9033_TUNER_IT9135_38;
862df8f1be1SAntti Palosaari 			state->af9033_config[1].tuner = AF9033_TUNER_IT9135_38;
863bc3c9e10SAntti Palosaari 		}
864bc3c9e10SAntti Palosaari 
86509bfd96cSAntti Palosaari 		if (state->no_eeprom) {
86609bfd96cSAntti Palosaari 			/* Remote controller to NEC polling by default */
86709bfd96cSAntti Palosaari 			state->ir_mode = 0x05;
86809bfd96cSAntti Palosaari 			state->ir_type = 0x00;
8699ea3681dSAntti Palosaari 
8709ea3681dSAntti Palosaari 			goto skip_eeprom;
8719ea3681dSAntti Palosaari 		}
8725b556084SOlli Salonen 	} else if (state->chip_type == 0x9306) {
8735b556084SOlli Salonen 		/*
8745b556084SOlli Salonen 		 * IT930x is an USB bridge, only single demod-single tuner
8755b556084SOlli Salonen 		 * configurations seen so far.
8765b556084SOlli Salonen 		 */
8775b556084SOlli Salonen 		return 0;
8789ea3681dSAntti Palosaari 	}
8799ea3681dSAntti Palosaari 
88009bfd96cSAntti Palosaari 	/* Remote controller */
88109bfd96cSAntti Palosaari 	state->ir_mode = state->eeprom[EEPROM_IR_MODE];
88209bfd96cSAntti Palosaari 	state->ir_type = state->eeprom[EEPROM_IR_TYPE];
8835b556084SOlli Salonen 
8849805992fSJose Alberto Reguero 	if (state->dual_mode) {
8859805992fSJose Alberto Reguero 		/* read 2nd demodulator I2C address */
88609bfd96cSAntti Palosaari 		tmp = state->eeprom[EEPROM_2ND_DEMOD_ADDR];
88714992f01SAntti Palosaari 		if (tmp)
888a781edd1SAntti Palosaari 			state->af9033_i2c_addr[1] = tmp;
88914992f01SAntti Palosaari 
8902b987ea7SAntti Palosaari 		dev_dbg(&intf->dev, "2nd demod I2C addr=%02x\n", tmp);
8919805992fSJose Alberto Reguero 	}
8929805992fSJose Alberto Reguero 
893786baecfSMauro Carvalho Chehab 	for (i = 0; i < state->dual_mode + 1; i++) {
89409bfd96cSAntti Palosaari 		unsigned int eeprom_offset = 0;
895786baecfSMauro Carvalho Chehab 
89609bfd96cSAntti Palosaari 		/* tuner */
89709bfd96cSAntti Palosaari 		tmp = state->eeprom[EEPROM_1_TUNER_ID + eeprom_offset];
8982b987ea7SAntti Palosaari 		dev_dbg(&intf->dev, "[%d]tuner=%02x\n", i, tmp);
8991cbbf90dSAntti Palosaari 
9001cbbf90dSAntti Palosaari 		/* tuner sanity check */
9011cbbf90dSAntti Palosaari 		if (state->chip_type == 0x9135) {
9021cbbf90dSAntti Palosaari 			if (state->chip_version == 0x02) {
9031cbbf90dSAntti Palosaari 				/* IT9135 BX (v2) */
9041cbbf90dSAntti Palosaari 				switch (tmp) {
9051cbbf90dSAntti Palosaari 				case AF9033_TUNER_IT9135_60:
9061cbbf90dSAntti Palosaari 				case AF9033_TUNER_IT9135_61:
9071cbbf90dSAntti Palosaari 				case AF9033_TUNER_IT9135_62:
9081cbbf90dSAntti Palosaari 					state->af9033_config[i].tuner = tmp;
9091cbbf90dSAntti Palosaari 					break;
9101cbbf90dSAntti Palosaari 				}
9111cbbf90dSAntti Palosaari 			} else {
9121cbbf90dSAntti Palosaari 				/* IT9135 AX (v1) */
9131cbbf90dSAntti Palosaari 				switch (tmp) {
9141cbbf90dSAntti Palosaari 				case AF9033_TUNER_IT9135_38:
9151cbbf90dSAntti Palosaari 				case AF9033_TUNER_IT9135_51:
9161cbbf90dSAntti Palosaari 				case AF9033_TUNER_IT9135_52:
9171cbbf90dSAntti Palosaari 					state->af9033_config[i].tuner = tmp;
9181cbbf90dSAntti Palosaari 					break;
9191cbbf90dSAntti Palosaari 				}
9201cbbf90dSAntti Palosaari 			}
9211cbbf90dSAntti Palosaari 		} else {
9221cbbf90dSAntti Palosaari 			/* AF9035 */
9231cbbf90dSAntti Palosaari 			state->af9033_config[i].tuner = tmp;
9241cbbf90dSAntti Palosaari 		}
9251cbbf90dSAntti Palosaari 
9261cbbf90dSAntti Palosaari 		if (state->af9033_config[i].tuner != tmp) {
9272b987ea7SAntti Palosaari 			dev_info(&intf->dev, "[%d] overriding tuner from %02x to %02x\n",
9282b987ea7SAntti Palosaari 				 i, tmp, state->af9033_config[i].tuner);
9291cbbf90dSAntti Palosaari 		}
9309ea3681dSAntti Palosaari 
9319ea3681dSAntti Palosaari 		switch (state->af9033_config[i].tuner) {
932786baecfSMauro Carvalho Chehab 		case AF9033_TUNER_TUA9001:
933786baecfSMauro Carvalho Chehab 		case AF9033_TUNER_FC0011:
934786baecfSMauro Carvalho Chehab 		case AF9033_TUNER_MXL5007T:
935786baecfSMauro Carvalho Chehab 		case AF9033_TUNER_TDA18218:
936d67ceb33SOliver Schinagl 		case AF9033_TUNER_FC2580:
9377e0bc296SAntti Palosaari 		case AF9033_TUNER_FC0012:
938786baecfSMauro Carvalho Chehab 			state->af9033_config[i].spec_inv = 1;
939786baecfSMauro Carvalho Chehab 			break;
9409ea3681dSAntti Palosaari 		case AF9033_TUNER_IT9135_38:
9419ea3681dSAntti Palosaari 		case AF9033_TUNER_IT9135_51:
9429ea3681dSAntti Palosaari 		case AF9033_TUNER_IT9135_52:
9439ea3681dSAntti Palosaari 		case AF9033_TUNER_IT9135_60:
9449ea3681dSAntti Palosaari 		case AF9033_TUNER_IT9135_61:
9459ea3681dSAntti Palosaari 		case AF9033_TUNER_IT9135_62:
9469ea3681dSAntti Palosaari 			break;
947786baecfSMauro Carvalho Chehab 		default:
9482b987ea7SAntti Palosaari 			dev_warn(&intf->dev, "tuner id=%02x not supported, please report!",
9492b987ea7SAntti Palosaari 				 tmp);
950c2c1b415SPeter Senna Tschudin 		}
951786baecfSMauro Carvalho Chehab 
952bf97b637SAntti Palosaari 		/* disable dual mode if driver does not support it */
953bf97b637SAntti Palosaari 		if (i == 1)
954df8f1be1SAntti Palosaari 			switch (state->af9033_config[i].tuner) {
9550bb3d8acSAntti Palosaari 			case AF9033_TUNER_FC0012:
956df8f1be1SAntti Palosaari 			case AF9033_TUNER_IT9135_38:
957df8f1be1SAntti Palosaari 			case AF9033_TUNER_IT9135_51:
958df8f1be1SAntti Palosaari 			case AF9033_TUNER_IT9135_52:
959df8f1be1SAntti Palosaari 			case AF9033_TUNER_IT9135_60:
960df8f1be1SAntti Palosaari 			case AF9033_TUNER_IT9135_61:
961df8f1be1SAntti Palosaari 			case AF9033_TUNER_IT9135_62:
96278c7bc4bSJose Alberto Reguero 			case AF9033_TUNER_MXL5007T:
9630bb3d8acSAntti Palosaari 				break;
964bf97b637SAntti Palosaari 			default:
965bf97b637SAntti Palosaari 				state->dual_mode = false;
9662b987ea7SAntti Palosaari 				dev_info(&intf->dev, "driver does not support 2nd tuner and will disable it");
967bf97b637SAntti Palosaari 		}
968bf97b637SAntti Palosaari 
969786baecfSMauro Carvalho Chehab 		/* tuner IF frequency */
97009bfd96cSAntti Palosaari 		tmp = state->eeprom[EEPROM_1_IF_L + eeprom_offset];
97109bfd96cSAntti Palosaari 		tmp16 = tmp << 0;
97209bfd96cSAntti Palosaari 		tmp = state->eeprom[EEPROM_1_IF_H + eeprom_offset];
973786baecfSMauro Carvalho Chehab 		tmp16 |= tmp << 8;
9742b987ea7SAntti Palosaari 		dev_dbg(&intf->dev, "[%d]IF=%d\n", i, tmp16);
975786baecfSMauro Carvalho Chehab 
97609bfd96cSAntti Palosaari 		eeprom_offset += 0x10; /* shift for the 2nd tuner params */
977786baecfSMauro Carvalho Chehab 	}
978786baecfSMauro Carvalho Chehab 
9799ea3681dSAntti Palosaari skip_eeprom:
980786baecfSMauro Carvalho Chehab 	/* get demod clock */
981786baecfSMauro Carvalho Chehab 	ret = af9035_rd_reg(d, 0x00d800, &tmp);
982786baecfSMauro Carvalho Chehab 	if (ret < 0)
983786baecfSMauro Carvalho Chehab 		goto err;
984786baecfSMauro Carvalho Chehab 
985786baecfSMauro Carvalho Chehab 	tmp = (tmp >> 0) & 0x0f;
986786baecfSMauro Carvalho Chehab 
9879ea3681dSAntti Palosaari 	for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++) {
98874c1883aSAntti Palosaari 		if (state->chip_type == 0x9135)
9899ea3681dSAntti Palosaari 			state->af9033_config[i].clock = clock_lut_it9135[tmp];
99074c1883aSAntti Palosaari 		else
9919ea3681dSAntti Palosaari 			state->af9033_config[i].clock = clock_lut_af9035[tmp];
9929ea3681dSAntti Palosaari 	}
9939ea3681dSAntti Palosaari 
9941882f59fSAlessandro Radicati 	state->no_read = false;
9951882f59fSAlessandro Radicati 	/* Some MXL5007T devices cannot properly handle tuner I2C read ops. */
9961882f59fSAlessandro Radicati 	if (state->af9033_config[0].tuner == AF9033_TUNER_MXL5007T &&
9971882f59fSAlessandro Radicati 		le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA)
9981882f59fSAlessandro Radicati 
9991882f59fSAlessandro Radicati 		switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
10001882f59fSAlessandro Radicati 		case USB_PID_AVERMEDIA_A867:
10011882f59fSAlessandro Radicati 		case USB_PID_AVERMEDIA_TWINSTAR:
10022b987ea7SAntti Palosaari 			dev_info(&intf->dev,
10032b987ea7SAntti Palosaari 				 "Device may have issues with I2C read operations. Enabling fix.\n");
10041882f59fSAlessandro Radicati 			state->no_read = true;
10051882f59fSAlessandro Radicati 			break;
10061882f59fSAlessandro Radicati 		}
10071882f59fSAlessandro Radicati 
10089ea3681dSAntti Palosaari 	return 0;
10099ea3681dSAntti Palosaari 
10109ea3681dSAntti Palosaari err:
10112b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
10129ea3681dSAntti Palosaari 
10139ea3681dSAntti Palosaari 	return ret;
101474c1883aSAntti Palosaari }
101574c1883aSAntti Palosaari 
101651639be3SAntti Palosaari static int af9035_tua9001_tuner_callback(struct dvb_usb_device *d,
101751639be3SAntti Palosaari 		int cmd, int arg)
101851639be3SAntti Palosaari {
10192b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
102051639be3SAntti Palosaari 	int ret;
102151639be3SAntti Palosaari 	u8 val;
102251639be3SAntti Palosaari 
10232b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "cmd=%d arg=%d\n", cmd, arg);
102451639be3SAntti Palosaari 
102551639be3SAntti Palosaari 	/*
102651639be3SAntti Palosaari 	 * CEN     always enabled by hardware wiring
102751639be3SAntti Palosaari 	 * RESETN  GPIOT3
102851639be3SAntti Palosaari 	 * RXEN    GPIOT2
102951639be3SAntti Palosaari 	 */
103051639be3SAntti Palosaari 
103151639be3SAntti Palosaari 	switch (cmd) {
103251639be3SAntti Palosaari 	case TUA9001_CMD_RESETN:
103351639be3SAntti Palosaari 		if (arg)
103451639be3SAntti Palosaari 			val = 0x00;
103551639be3SAntti Palosaari 		else
103651639be3SAntti Palosaari 			val = 0x01;
103751639be3SAntti Palosaari 
103851639be3SAntti Palosaari 		ret = af9035_wr_reg_mask(d, 0x00d8e7, val, 0x01);
103951639be3SAntti Palosaari 		if (ret < 0)
104051639be3SAntti Palosaari 			goto err;
104151639be3SAntti Palosaari 		break;
104251639be3SAntti Palosaari 	case TUA9001_CMD_RXEN:
104351639be3SAntti Palosaari 		if (arg)
104451639be3SAntti Palosaari 			val = 0x01;
104551639be3SAntti Palosaari 		else
104651639be3SAntti Palosaari 			val = 0x00;
104751639be3SAntti Palosaari 
104851639be3SAntti Palosaari 		ret = af9035_wr_reg_mask(d, 0x00d8eb, val, 0x01);
104951639be3SAntti Palosaari 		if (ret < 0)
105051639be3SAntti Palosaari 			goto err;
105151639be3SAntti Palosaari 		break;
105251639be3SAntti Palosaari 	}
105351639be3SAntti Palosaari 
105451639be3SAntti Palosaari 	return 0;
105551639be3SAntti Palosaari 
105651639be3SAntti Palosaari err:
10572b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
105851639be3SAntti Palosaari 
105951639be3SAntti Palosaari 	return ret;
106051639be3SAntti Palosaari }
106151639be3SAntti Palosaari 
106251639be3SAntti Palosaari 
1063786baecfSMauro Carvalho Chehab static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
1064786baecfSMauro Carvalho Chehab 		int cmd, int arg)
1065786baecfSMauro Carvalho Chehab {
10662b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1067786baecfSMauro Carvalho Chehab 	int ret;
1068786baecfSMauro Carvalho Chehab 
1069786baecfSMauro Carvalho Chehab 	switch (cmd) {
1070786baecfSMauro Carvalho Chehab 	case FC0011_FE_CALLBACK_POWER:
1071786baecfSMauro Carvalho Chehab 		/* Tuner enable */
1072786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg_mask(d, 0xd8eb, 1, 1);
1073786baecfSMauro Carvalho Chehab 		if (ret < 0)
1074786baecfSMauro Carvalho Chehab 			goto err;
1075786baecfSMauro Carvalho Chehab 
1076786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg_mask(d, 0xd8ec, 1, 1);
1077786baecfSMauro Carvalho Chehab 		if (ret < 0)
1078786baecfSMauro Carvalho Chehab 			goto err;
1079786baecfSMauro Carvalho Chehab 
1080786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg_mask(d, 0xd8ed, 1, 1);
1081786baecfSMauro Carvalho Chehab 		if (ret < 0)
1082786baecfSMauro Carvalho Chehab 			goto err;
1083786baecfSMauro Carvalho Chehab 
1084786baecfSMauro Carvalho Chehab 		/* LED */
1085786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg_mask(d, 0xd8d0, 1, 1);
1086786baecfSMauro Carvalho Chehab 		if (ret < 0)
1087786baecfSMauro Carvalho Chehab 			goto err;
1088786baecfSMauro Carvalho Chehab 
1089786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg_mask(d, 0xd8d1, 1, 1);
1090786baecfSMauro Carvalho Chehab 		if (ret < 0)
1091786baecfSMauro Carvalho Chehab 			goto err;
1092786baecfSMauro Carvalho Chehab 
1093786baecfSMauro Carvalho Chehab 		usleep_range(10000, 50000);
1094786baecfSMauro Carvalho Chehab 		break;
1095786baecfSMauro Carvalho Chehab 	case FC0011_FE_CALLBACK_RESET:
1096786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg(d, 0xd8e9, 1);
1097786baecfSMauro Carvalho Chehab 		if (ret < 0)
1098786baecfSMauro Carvalho Chehab 			goto err;
1099786baecfSMauro Carvalho Chehab 
1100786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg(d, 0xd8e8, 1);
1101786baecfSMauro Carvalho Chehab 		if (ret < 0)
1102786baecfSMauro Carvalho Chehab 			goto err;
1103786baecfSMauro Carvalho Chehab 
1104786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg(d, 0xd8e7, 1);
1105786baecfSMauro Carvalho Chehab 		if (ret < 0)
1106786baecfSMauro Carvalho Chehab 			goto err;
1107786baecfSMauro Carvalho Chehab 
1108786baecfSMauro Carvalho Chehab 		usleep_range(10000, 20000);
1109786baecfSMauro Carvalho Chehab 
1110786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg(d, 0xd8e7, 0);
1111786baecfSMauro Carvalho Chehab 		if (ret < 0)
1112786baecfSMauro Carvalho Chehab 			goto err;
1113786baecfSMauro Carvalho Chehab 
1114786baecfSMauro Carvalho Chehab 		usleep_range(10000, 20000);
1115786baecfSMauro Carvalho Chehab 		break;
1116786baecfSMauro Carvalho Chehab 	default:
1117786baecfSMauro Carvalho Chehab 		ret = -EINVAL;
1118786baecfSMauro Carvalho Chehab 		goto err;
1119786baecfSMauro Carvalho Chehab 	}
1120786baecfSMauro Carvalho Chehab 
1121786baecfSMauro Carvalho Chehab 	return 0;
1122786baecfSMauro Carvalho Chehab 
1123786baecfSMauro Carvalho Chehab err:
11242b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
1125786baecfSMauro Carvalho Chehab 
1126786baecfSMauro Carvalho Chehab 	return ret;
1127786baecfSMauro Carvalho Chehab }
1128786baecfSMauro Carvalho Chehab 
1129786baecfSMauro Carvalho Chehab static int af9035_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
1130786baecfSMauro Carvalho Chehab {
1131786baecfSMauro Carvalho Chehab 	struct state *state = d_to_priv(d);
1132786baecfSMauro Carvalho Chehab 
1133786baecfSMauro Carvalho Chehab 	switch (state->af9033_config[0].tuner) {
1134786baecfSMauro Carvalho Chehab 	case AF9033_TUNER_FC0011:
1135786baecfSMauro Carvalho Chehab 		return af9035_fc0011_tuner_callback(d, cmd, arg);
113651639be3SAntti Palosaari 	case AF9033_TUNER_TUA9001:
113751639be3SAntti Palosaari 		return af9035_tua9001_tuner_callback(d, cmd, arg);
1138786baecfSMauro Carvalho Chehab 	default:
1139786baecfSMauro Carvalho Chehab 		break;
1140786baecfSMauro Carvalho Chehab 	}
1141786baecfSMauro Carvalho Chehab 
11421835af10SAntti Palosaari 	return 0;
1143786baecfSMauro Carvalho Chehab }
1144786baecfSMauro Carvalho Chehab 
1145786baecfSMauro Carvalho Chehab static int af9035_frontend_callback(void *adapter_priv, int component,
1146786baecfSMauro Carvalho Chehab 				    int cmd, int arg)
1147786baecfSMauro Carvalho Chehab {
1148786baecfSMauro Carvalho Chehab 	struct i2c_adapter *adap = adapter_priv;
1149786baecfSMauro Carvalho Chehab 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
11502b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1151786baecfSMauro Carvalho Chehab 
11522b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "component=%d cmd=%d arg=%d\n",
11532b987ea7SAntti Palosaari 		component, cmd, arg);
11541835af10SAntti Palosaari 
1155786baecfSMauro Carvalho Chehab 	switch (component) {
1156786baecfSMauro Carvalho Chehab 	case DVB_FRONTEND_COMPONENT_TUNER:
1157786baecfSMauro Carvalho Chehab 		return af9035_tuner_callback(d, cmd, arg);
1158786baecfSMauro Carvalho Chehab 	default:
1159786baecfSMauro Carvalho Chehab 		break;
1160786baecfSMauro Carvalho Chehab 	}
1161786baecfSMauro Carvalho Chehab 
11621835af10SAntti Palosaari 	return 0;
1163786baecfSMauro Carvalho Chehab }
1164786baecfSMauro Carvalho Chehab 
11659805992fSJose Alberto Reguero static int af9035_get_adapter_count(struct dvb_usb_device *d)
11669805992fSJose Alberto Reguero {
11679805992fSJose Alberto Reguero 	struct state *state = d_to_priv(d);
1168c10989a2SAntti Palosaari 
11699805992fSJose Alberto Reguero 	return state->dual_mode + 1;
11709805992fSJose Alberto Reguero }
11719805992fSJose Alberto Reguero 
1172786baecfSMauro Carvalho Chehab static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
1173786baecfSMauro Carvalho Chehab {
1174786baecfSMauro Carvalho Chehab 	struct state *state = adap_to_priv(adap);
1175786baecfSMauro Carvalho Chehab 	struct dvb_usb_device *d = adap_to_d(adap);
11762b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1177786baecfSMauro Carvalho Chehab 	int ret;
1178c10989a2SAntti Palosaari 
11792b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1180786baecfSMauro Carvalho Chehab 
1181786baecfSMauro Carvalho Chehab 	if (!state->af9033_config[adap->id].tuner) {
1182786baecfSMauro Carvalho Chehab 		/* unsupported tuner */
1183786baecfSMauro Carvalho Chehab 		ret = -ENODEV;
1184786baecfSMauro Carvalho Chehab 		goto err;
1185786baecfSMauro Carvalho Chehab 	}
1186786baecfSMauro Carvalho Chehab 
1187f5b00a76SAntti Palosaari 	state->af9033_config[adap->id].fe = &adap->fe[0];
1188f5b00a76SAntti Palosaari 	state->af9033_config[adap->id].ops = &state->ops;
1189a781edd1SAntti Palosaari 	ret = af9035_add_i2c_dev(d, "af9033", state->af9033_i2c_addr[adap->id],
11905dcf5bf6SOlli Salonen 			&state->af9033_config[adap->id], &d->i2c_adap);
1191f5b00a76SAntti Palosaari 	if (ret)
1192f5b00a76SAntti Palosaari 		goto err;
1193f5b00a76SAntti Palosaari 
1194786baecfSMauro Carvalho Chehab 	if (adap->fe[0] == NULL) {
1195786baecfSMauro Carvalho Chehab 		ret = -ENODEV;
1196786baecfSMauro Carvalho Chehab 		goto err;
1197786baecfSMauro Carvalho Chehab 	}
1198786baecfSMauro Carvalho Chehab 
1199786baecfSMauro Carvalho Chehab 	/* disable I2C-gate */
1200786baecfSMauro Carvalho Chehab 	adap->fe[0]->ops.i2c_gate_ctrl = NULL;
1201786baecfSMauro Carvalho Chehab 	adap->fe[0]->callback = af9035_frontend_callback;
1202786baecfSMauro Carvalho Chehab 
1203786baecfSMauro Carvalho Chehab 	return 0;
1204786baecfSMauro Carvalho Chehab 
1205786baecfSMauro Carvalho Chehab err:
12062b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
1207786baecfSMauro Carvalho Chehab 
1208786baecfSMauro Carvalho Chehab 	return ret;
1209786baecfSMauro Carvalho Chehab }
1210786baecfSMauro Carvalho Chehab 
12115b556084SOlli Salonen static int it930x_frontend_attach(struct dvb_usb_adapter *adap)
12125b556084SOlli Salonen {
12135b556084SOlli Salonen 	struct state *state = adap_to_priv(adap);
12145b556084SOlli Salonen 	struct dvb_usb_device *d = adap_to_d(adap);
12152b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
12165b556084SOlli Salonen 	int ret;
12175b556084SOlli Salonen 	struct si2168_config si2168_config;
12185b556084SOlli Salonen 	struct i2c_adapter *adapter;
12195b556084SOlli Salonen 
12202b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
12215b556084SOlli Salonen 
1222251a5c4eSOlli Salonen 	memset(&si2168_config, 0, sizeof(si2168_config));
12235b556084SOlli Salonen 	si2168_config.i2c_adapter = &adapter;
12245b556084SOlli Salonen 	si2168_config.fe = &adap->fe[0];
12255b556084SOlli Salonen 	si2168_config.ts_mode = SI2168_TS_SERIAL;
12265b556084SOlli Salonen 
12275b556084SOlli Salonen 	state->af9033_config[adap->id].fe = &adap->fe[0];
12285b556084SOlli Salonen 	state->af9033_config[adap->id].ops = &state->ops;
12295b556084SOlli Salonen 	ret = af9035_add_i2c_dev(d, "si2168", 0x67, &si2168_config,
12305b556084SOlli Salonen 				&d->i2c_adap);
12315b556084SOlli Salonen 	if (ret)
12325b556084SOlli Salonen 		goto err;
12335b556084SOlli Salonen 
12345b556084SOlli Salonen 	if (adap->fe[0] == NULL) {
12355b556084SOlli Salonen 		ret = -ENODEV;
12365b556084SOlli Salonen 		goto err;
12375b556084SOlli Salonen 	}
12385b556084SOlli Salonen 	state->i2c_adapter_demod = adapter;
12395b556084SOlli Salonen 
12405b556084SOlli Salonen 	return 0;
12415b556084SOlli Salonen 
12425b556084SOlli Salonen err:
12432b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
12445b556084SOlli Salonen 
12455b556084SOlli Salonen 	return ret;
12465b556084SOlli Salonen }
12475b556084SOlli Salonen 
1248d4d6a34dSAntti Palosaari static int af9035_frontend_detach(struct dvb_usb_adapter *adap)
1249d4d6a34dSAntti Palosaari {
1250d4d6a34dSAntti Palosaari 	struct state *state = adap_to_priv(adap);
1251d4d6a34dSAntti Palosaari 	struct dvb_usb_device *d = adap_to_d(adap);
12522b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1253d4d6a34dSAntti Palosaari 	int demod2;
1254d4d6a34dSAntti Palosaari 
12552b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1256d4d6a34dSAntti Palosaari 
1257d4d6a34dSAntti Palosaari 	/*
1258d4d6a34dSAntti Palosaari 	 * For dual tuner devices we have to resolve 2nd demod client, as there
1259d4d6a34dSAntti Palosaari 	 * is two different kind of tuner drivers; one is using I2C binding
1260d4d6a34dSAntti Palosaari 	 * and the other is using DVB attach/detach binding.
1261d4d6a34dSAntti Palosaari 	 */
1262d4d6a34dSAntti Palosaari 	switch (state->af9033_config[adap->id].tuner) {
1263d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_38:
1264d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_51:
1265d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_52:
1266d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_60:
1267d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_61:
1268d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_62:
1269d4d6a34dSAntti Palosaari 		demod2 = 2;
1270d4d6a34dSAntti Palosaari 		break;
1271d4d6a34dSAntti Palosaari 	default:
1272d4d6a34dSAntti Palosaari 		demod2 = 1;
1273d4d6a34dSAntti Palosaari 	}
1274d4d6a34dSAntti Palosaari 
1275d4d6a34dSAntti Palosaari 	if (adap->id == 1) {
1276d4d6a34dSAntti Palosaari 		if (state->i2c_client[demod2])
1277d4d6a34dSAntti Palosaari 			af9035_del_i2c_dev(d);
1278d4d6a34dSAntti Palosaari 	} else if (adap->id == 0) {
1279d4d6a34dSAntti Palosaari 		if (state->i2c_client[0])
1280d4d6a34dSAntti Palosaari 			af9035_del_i2c_dev(d);
1281d4d6a34dSAntti Palosaari 	}
1282d4d6a34dSAntti Palosaari 
1283d4d6a34dSAntti Palosaari 	return 0;
1284d4d6a34dSAntti Palosaari }
1285d4d6a34dSAntti Palosaari 
1286786baecfSMauro Carvalho Chehab static const struct fc0011_config af9035_fc0011_config = {
1287786baecfSMauro Carvalho Chehab 	.i2c_address = 0x60,
1288786baecfSMauro Carvalho Chehab };
1289786baecfSMauro Carvalho Chehab 
12909805992fSJose Alberto Reguero static struct mxl5007t_config af9035_mxl5007t_config[] = {
12919805992fSJose Alberto Reguero 	{
1292786baecfSMauro Carvalho Chehab 		.xtal_freq_hz = MxL_XTAL_24_MHZ,
1293786baecfSMauro Carvalho Chehab 		.if_freq_hz = MxL_IF_4_57_MHZ,
1294786baecfSMauro Carvalho Chehab 		.invert_if = 0,
1295786baecfSMauro Carvalho Chehab 		.loop_thru_enable = 0,
1296786baecfSMauro Carvalho Chehab 		.clk_out_enable = 0,
1297786baecfSMauro Carvalho Chehab 		.clk_out_amp = MxL_CLKOUT_AMP_0_94V,
12989805992fSJose Alberto Reguero 	}, {
12999805992fSJose Alberto Reguero 		.xtal_freq_hz = MxL_XTAL_24_MHZ,
13009805992fSJose Alberto Reguero 		.if_freq_hz = MxL_IF_4_57_MHZ,
13019805992fSJose Alberto Reguero 		.invert_if = 0,
13029805992fSJose Alberto Reguero 		.loop_thru_enable = 1,
13039805992fSJose Alberto Reguero 		.clk_out_enable = 1,
13049805992fSJose Alberto Reguero 		.clk_out_amp = MxL_CLKOUT_AMP_0_94V,
13059805992fSJose Alberto Reguero 	}
1306786baecfSMauro Carvalho Chehab };
1307786baecfSMauro Carvalho Chehab 
1308786baecfSMauro Carvalho Chehab static struct tda18218_config af9035_tda18218_config = {
1309786baecfSMauro Carvalho Chehab 	.i2c_address = 0x60,
1310786baecfSMauro Carvalho Chehab 	.i2c_wr_max = 21,
1311786baecfSMauro Carvalho Chehab };
1312786baecfSMauro Carvalho Chehab 
13130bb3d8acSAntti Palosaari static const struct fc0012_config af9035_fc0012_config[] = {
13140bb3d8acSAntti Palosaari 	{
1315ad3a758bSAntti Palosaari 		.i2c_address = 0x63,
1316ad3a758bSAntti Palosaari 		.xtal_freq = FC_XTAL_36_MHZ,
13173a984772SAntti Palosaari 		.dual_master = true,
13180bb3d8acSAntti Palosaari 		.loop_through = true,
13190bb3d8acSAntti Palosaari 		.clock_out = true,
13200bb3d8acSAntti Palosaari 	}, {
13210bb3d8acSAntti Palosaari 		.i2c_address = 0x63 | 0x80, /* I2C bus select hack */
13220bb3d8acSAntti Palosaari 		.xtal_freq = FC_XTAL_36_MHZ,
13233a984772SAntti Palosaari 		.dual_master = true,
13240bb3d8acSAntti Palosaari 	}
1325ad3a758bSAntti Palosaari };
1326ad3a758bSAntti Palosaari 
1327786baecfSMauro Carvalho Chehab static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
1328786baecfSMauro Carvalho Chehab {
1329786baecfSMauro Carvalho Chehab 	struct state *state = adap_to_priv(adap);
1330786baecfSMauro Carvalho Chehab 	struct dvb_usb_device *d = adap_to_d(adap);
13312b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1332786baecfSMauro Carvalho Chehab 	int ret;
1333786baecfSMauro Carvalho Chehab 	struct dvb_frontend *fe;
13340bb3d8acSAntti Palosaari 	struct i2c_msg msg[1];
1335bf97b637SAntti Palosaari 	u8 tuner_addr;
1336c10989a2SAntti Palosaari 
13372b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1338df8f1be1SAntti Palosaari 
1339bf97b637SAntti Palosaari 	/*
1340bf97b637SAntti Palosaari 	 * XXX: Hack used in that function: we abuse unused I2C address bit [7]
1341bf97b637SAntti Palosaari 	 * to carry info about used I2C bus for dual tuner configuration.
1342bf97b637SAntti Palosaari 	 */
1343786baecfSMauro Carvalho Chehab 
1344786baecfSMauro Carvalho Chehab 	switch (state->af9033_config[adap->id].tuner) {
1345b6c5fe70SAntti Palosaari 	case AF9033_TUNER_TUA9001: {
1346b6c5fe70SAntti Palosaari 		struct tua9001_platform_data tua9001_pdata = {
1347b6c5fe70SAntti Palosaari 			.dvb_frontend = adap->fe[0],
1348b6c5fe70SAntti Palosaari 		};
1349b6c5fe70SAntti Palosaari 
1350b6c5fe70SAntti Palosaari 		/*
1351b6c5fe70SAntti Palosaari 		 * AF9035 gpiot3 = TUA9001 RESETN
1352b6c5fe70SAntti Palosaari 		 * AF9035 gpiot2 = TUA9001 RXEN
1353b6c5fe70SAntti Palosaari 		 */
1354786baecfSMauro Carvalho Chehab 
1355786baecfSMauro Carvalho Chehab 		/* configure gpiot2 and gpiot2 as output */
1356786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg_mask(d, 0x00d8ec, 0x01, 0x01);
1357786baecfSMauro Carvalho Chehab 		if (ret < 0)
1358786baecfSMauro Carvalho Chehab 			goto err;
1359786baecfSMauro Carvalho Chehab 
1360786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg_mask(d, 0x00d8ed, 0x01, 0x01);
1361786baecfSMauro Carvalho Chehab 		if (ret < 0)
1362786baecfSMauro Carvalho Chehab 			goto err;
1363786baecfSMauro Carvalho Chehab 
1364786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg_mask(d, 0x00d8e8, 0x01, 0x01);
1365786baecfSMauro Carvalho Chehab 		if (ret < 0)
1366786baecfSMauro Carvalho Chehab 			goto err;
1367786baecfSMauro Carvalho Chehab 
1368786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg_mask(d, 0x00d8e9, 0x01, 0x01);
1369786baecfSMauro Carvalho Chehab 		if (ret < 0)
1370786baecfSMauro Carvalho Chehab 			goto err;
1371786baecfSMauro Carvalho Chehab 
1372786baecfSMauro Carvalho Chehab 		/* attach tuner */
1373b6c5fe70SAntti Palosaari 		ret = af9035_add_i2c_dev(d, "tua9001", 0x60, &tua9001_pdata,
1374b6c5fe70SAntti Palosaari 					 &d->i2c_adap);
1375b6c5fe70SAntti Palosaari 		if (ret)
1376b6c5fe70SAntti Palosaari 			goto err;
1377b6c5fe70SAntti Palosaari 
1378b6c5fe70SAntti Palosaari 		fe = adap->fe[0];
1379786baecfSMauro Carvalho Chehab 		break;
1380b6c5fe70SAntti Palosaari 	}
1381786baecfSMauro Carvalho Chehab 	case AF9033_TUNER_FC0011:
1382786baecfSMauro Carvalho Chehab 		fe = dvb_attach(fc0011_attach, adap->fe[0],
1383786baecfSMauro Carvalho Chehab 				&d->i2c_adap, &af9035_fc0011_config);
1384786baecfSMauro Carvalho Chehab 		break;
1385786baecfSMauro Carvalho Chehab 	case AF9033_TUNER_MXL5007T:
13869805992fSJose Alberto Reguero 		if (adap->id == 0) {
1387786baecfSMauro Carvalho Chehab 			ret = af9035_wr_reg(d, 0x00d8e0, 1);
1388786baecfSMauro Carvalho Chehab 			if (ret < 0)
1389786baecfSMauro Carvalho Chehab 				goto err;
1390bf97b637SAntti Palosaari 
1391786baecfSMauro Carvalho Chehab 			ret = af9035_wr_reg(d, 0x00d8e1, 1);
1392786baecfSMauro Carvalho Chehab 			if (ret < 0)
1393786baecfSMauro Carvalho Chehab 				goto err;
1394bf97b637SAntti Palosaari 
1395786baecfSMauro Carvalho Chehab 			ret = af9035_wr_reg(d, 0x00d8df, 0);
1396786baecfSMauro Carvalho Chehab 			if (ret < 0)
1397786baecfSMauro Carvalho Chehab 				goto err;
1398786baecfSMauro Carvalho Chehab 
1399786baecfSMauro Carvalho Chehab 			msleep(30);
1400786baecfSMauro Carvalho Chehab 
1401786baecfSMauro Carvalho Chehab 			ret = af9035_wr_reg(d, 0x00d8df, 1);
1402786baecfSMauro Carvalho Chehab 			if (ret < 0)
1403786baecfSMauro Carvalho Chehab 				goto err;
1404786baecfSMauro Carvalho Chehab 
1405786baecfSMauro Carvalho Chehab 			msleep(300);
1406786baecfSMauro Carvalho Chehab 
1407786baecfSMauro Carvalho Chehab 			ret = af9035_wr_reg(d, 0x00d8c0, 1);
1408786baecfSMauro Carvalho Chehab 			if (ret < 0)
1409786baecfSMauro Carvalho Chehab 				goto err;
1410bf97b637SAntti Palosaari 
1411786baecfSMauro Carvalho Chehab 			ret = af9035_wr_reg(d, 0x00d8c1, 1);
1412786baecfSMauro Carvalho Chehab 			if (ret < 0)
1413786baecfSMauro Carvalho Chehab 				goto err;
1414bf97b637SAntti Palosaari 
1415786baecfSMauro Carvalho Chehab 			ret = af9035_wr_reg(d, 0x00d8bf, 0);
1416786baecfSMauro Carvalho Chehab 			if (ret < 0)
1417786baecfSMauro Carvalho Chehab 				goto err;
1418bf97b637SAntti Palosaari 
1419786baecfSMauro Carvalho Chehab 			ret = af9035_wr_reg(d, 0x00d8b4, 1);
1420786baecfSMauro Carvalho Chehab 			if (ret < 0)
1421786baecfSMauro Carvalho Chehab 				goto err;
1422bf97b637SAntti Palosaari 
1423786baecfSMauro Carvalho Chehab 			ret = af9035_wr_reg(d, 0x00d8b5, 1);
1424786baecfSMauro Carvalho Chehab 			if (ret < 0)
1425786baecfSMauro Carvalho Chehab 				goto err;
1426bf97b637SAntti Palosaari 
1427786baecfSMauro Carvalho Chehab 			ret = af9035_wr_reg(d, 0x00d8b3, 1);
1428786baecfSMauro Carvalho Chehab 			if (ret < 0)
1429786baecfSMauro Carvalho Chehab 				goto err;
1430bf97b637SAntti Palosaari 
1431bf97b637SAntti Palosaari 			tuner_addr = 0x60;
1432bf97b637SAntti Palosaari 		} else {
1433bf97b637SAntti Palosaari 			tuner_addr = 0x60 | 0x80; /* I2C bus hack */
14349805992fSJose Alberto Reguero 		}
1435786baecfSMauro Carvalho Chehab 
1436786baecfSMauro Carvalho Chehab 		/* attach tuner */
1437bf97b637SAntti Palosaari 		fe = dvb_attach(mxl5007t_attach, adap->fe[0], &d->i2c_adap,
1438bf97b637SAntti Palosaari 				tuner_addr, &af9035_mxl5007t_config[adap->id]);
1439786baecfSMauro Carvalho Chehab 		break;
1440786baecfSMauro Carvalho Chehab 	case AF9033_TUNER_TDA18218:
1441786baecfSMauro Carvalho Chehab 		/* attach tuner */
1442786baecfSMauro Carvalho Chehab 		fe = dvb_attach(tda18218_attach, adap->fe[0],
1443786baecfSMauro Carvalho Chehab 				&d->i2c_adap, &af9035_tda18218_config);
1444786baecfSMauro Carvalho Chehab 		break;
14457a893ba9SAntti Palosaari 	case AF9033_TUNER_FC2580: {
14467a893ba9SAntti Palosaari 		struct fc2580_platform_data fc2580_pdata = {
14477a893ba9SAntti Palosaari 			.dvb_frontend = adap->fe[0],
14487a893ba9SAntti Palosaari 		};
14497a893ba9SAntti Palosaari 
1450d67ceb33SOliver Schinagl 		/* Tuner enable using gpiot2_o, gpiot2_en and gpiot2_on  */
1451d67ceb33SOliver Schinagl 		ret = af9035_wr_reg_mask(d, 0xd8eb, 0x01, 0x01);
1452d67ceb33SOliver Schinagl 		if (ret < 0)
1453d67ceb33SOliver Schinagl 			goto err;
1454d67ceb33SOliver Schinagl 
1455d67ceb33SOliver Schinagl 		ret = af9035_wr_reg_mask(d, 0xd8ec, 0x01, 0x01);
1456d67ceb33SOliver Schinagl 		if (ret < 0)
1457d67ceb33SOliver Schinagl 			goto err;
1458d67ceb33SOliver Schinagl 
1459d67ceb33SOliver Schinagl 		ret = af9035_wr_reg_mask(d, 0xd8ed, 0x01, 0x01);
1460d67ceb33SOliver Schinagl 		if (ret < 0)
1461d67ceb33SOliver Schinagl 			goto err;
1462d67ceb33SOliver Schinagl 
1463d67ceb33SOliver Schinagl 		usleep_range(10000, 50000);
1464d67ceb33SOliver Schinagl 		/* attach tuner */
14657a893ba9SAntti Palosaari 		ret = af9035_add_i2c_dev(d, "fc2580", 0x56, &fc2580_pdata,
14667a893ba9SAntti Palosaari 					 &d->i2c_adap);
14677a893ba9SAntti Palosaari 		if (ret)
14687a893ba9SAntti Palosaari 			goto err;
14697a893ba9SAntti Palosaari 
14707a893ba9SAntti Palosaari 		fe = adap->fe[0];
1471d67ceb33SOliver Schinagl 		break;
14727a893ba9SAntti Palosaari 	}
14737e0bc296SAntti Palosaari 	case AF9033_TUNER_FC0012:
14747e0bc296SAntti Palosaari 		/*
14757e0bc296SAntti Palosaari 		 * AF9035 gpiot2 = FC0012 enable
14767e0bc296SAntti Palosaari 		 * XXX: there seems to be something on gpioh8 too, but on my
14777e0bc296SAntti Palosaari 		 * my test I didn't find any difference.
14787e0bc296SAntti Palosaari 		 */
14797e0bc296SAntti Palosaari 
14800bb3d8acSAntti Palosaari 		if (adap->id == 0) {
14817e0bc296SAntti Palosaari 			/* configure gpiot2 as output and high */
14827e0bc296SAntti Palosaari 			ret = af9035_wr_reg_mask(d, 0xd8eb, 0x01, 0x01);
14837e0bc296SAntti Palosaari 			if (ret < 0)
14847e0bc296SAntti Palosaari 				goto err;
14857e0bc296SAntti Palosaari 
14867e0bc296SAntti Palosaari 			ret = af9035_wr_reg_mask(d, 0xd8ec, 0x01, 0x01);
14877e0bc296SAntti Palosaari 			if (ret < 0)
14887e0bc296SAntti Palosaari 				goto err;
14897e0bc296SAntti Palosaari 
14907e0bc296SAntti Palosaari 			ret = af9035_wr_reg_mask(d, 0xd8ed, 0x01, 0x01);
14917e0bc296SAntti Palosaari 			if (ret < 0)
14927e0bc296SAntti Palosaari 				goto err;
14930bb3d8acSAntti Palosaari 		} else {
14940bb3d8acSAntti Palosaari 			/*
14950bb3d8acSAntti Palosaari 			 * FIXME: That belongs for the FC0012 driver.
14960bb3d8acSAntti Palosaari 			 * Write 02 to FC0012 master tuner register 0d directly
14970bb3d8acSAntti Palosaari 			 * in order to make slave tuner working.
14980bb3d8acSAntti Palosaari 			 */
14990bb3d8acSAntti Palosaari 			msg[0].addr = 0x63;
15000bb3d8acSAntti Palosaari 			msg[0].flags = 0;
15010bb3d8acSAntti Palosaari 			msg[0].len = 2;
15020bb3d8acSAntti Palosaari 			msg[0].buf = "\x0d\x02";
15030bb3d8acSAntti Palosaari 			ret = i2c_transfer(&d->i2c_adap, msg, 1);
15040bb3d8acSAntti Palosaari 			if (ret < 0)
15050bb3d8acSAntti Palosaari 				goto err;
15060bb3d8acSAntti Palosaari 		}
15077e0bc296SAntti Palosaari 
15087e0bc296SAntti Palosaari 		usleep_range(10000, 50000);
15097e0bc296SAntti Palosaari 
1510ad3a758bSAntti Palosaari 		fe = dvb_attach(fc0012_attach, adap->fe[0], &d->i2c_adap,
15110bb3d8acSAntti Palosaari 				&af9035_fc0012_config[adap->id]);
15127e0bc296SAntti Palosaari 		break;
1513ac77fb0fSAntti Palosaari 	case AF9033_TUNER_IT9135_38:
151474c1883aSAntti Palosaari 	case AF9033_TUNER_IT9135_51:
151574c1883aSAntti Palosaari 	case AF9033_TUNER_IT9135_52:
15163b2a5e8cSAntti Palosaari 	{
15173b2a5e8cSAntti Palosaari 		struct it913x_config it913x_config = {
15183b2a5e8cSAntti Palosaari 			.fe = adap->fe[0],
15193b2a5e8cSAntti Palosaari 			.chip_ver = 1,
15203b2a5e8cSAntti Palosaari 		};
15213b2a5e8cSAntti Palosaari 
1522676c350fSAntti Palosaari 		if (state->dual_mode) {
1523676c350fSAntti Palosaari 			if (adap->id == 0)
1524676c350fSAntti Palosaari 				it913x_config.role = IT913X_ROLE_DUAL_MASTER;
1525676c350fSAntti Palosaari 			else
1526676c350fSAntti Palosaari 				it913x_config.role = IT913X_ROLE_DUAL_SLAVE;
1527676c350fSAntti Palosaari 		}
1528676c350fSAntti Palosaari 
15293b2a5e8cSAntti Palosaari 		ret = af9035_add_i2c_dev(d, "it913x",
1530a781edd1SAntti Palosaari 				state->af9033_i2c_addr[adap->id] >> 1,
15315dcf5bf6SOlli Salonen 				&it913x_config, &d->i2c_adap);
15323b2a5e8cSAntti Palosaari 		if (ret)
15333b2a5e8cSAntti Palosaari 			goto err;
15343b2a5e8cSAntti Palosaari 
15353b2a5e8cSAntti Palosaari 		fe = adap->fe[0];
15363b2a5e8cSAntti Palosaari 		break;
15373b2a5e8cSAntti Palosaari 	}
153874c1883aSAntti Palosaari 	case AF9033_TUNER_IT9135_60:
153974c1883aSAntti Palosaari 	case AF9033_TUNER_IT9135_61:
154074c1883aSAntti Palosaari 	case AF9033_TUNER_IT9135_62:
15413b2a5e8cSAntti Palosaari 	{
15423b2a5e8cSAntti Palosaari 		struct it913x_config it913x_config = {
15433b2a5e8cSAntti Palosaari 			.fe = adap->fe[0],
15443b2a5e8cSAntti Palosaari 			.chip_ver = 2,
15453b2a5e8cSAntti Palosaari 		};
15463b2a5e8cSAntti Palosaari 
1547676c350fSAntti Palosaari 		if (state->dual_mode) {
1548676c350fSAntti Palosaari 			if (adap->id == 0)
1549676c350fSAntti Palosaari 				it913x_config.role = IT913X_ROLE_DUAL_MASTER;
1550676c350fSAntti Palosaari 			else
1551676c350fSAntti Palosaari 				it913x_config.role = IT913X_ROLE_DUAL_SLAVE;
1552676c350fSAntti Palosaari 		}
1553676c350fSAntti Palosaari 
15543b2a5e8cSAntti Palosaari 		ret = af9035_add_i2c_dev(d, "it913x",
1555a781edd1SAntti Palosaari 				state->af9033_i2c_addr[adap->id] >> 1,
15565dcf5bf6SOlli Salonen 				&it913x_config, &d->i2c_adap);
15573b2a5e8cSAntti Palosaari 		if (ret)
15583b2a5e8cSAntti Palosaari 			goto err;
15593b2a5e8cSAntti Palosaari 
15603b2a5e8cSAntti Palosaari 		fe = adap->fe[0];
1561ac77fb0fSAntti Palosaari 		break;
15623b2a5e8cSAntti Palosaari 	}
1563786baecfSMauro Carvalho Chehab 	default:
1564786baecfSMauro Carvalho Chehab 		fe = NULL;
1565786baecfSMauro Carvalho Chehab 	}
1566786baecfSMauro Carvalho Chehab 
1567786baecfSMauro Carvalho Chehab 	if (fe == NULL) {
1568786baecfSMauro Carvalho Chehab 		ret = -ENODEV;
1569786baecfSMauro Carvalho Chehab 		goto err;
1570786baecfSMauro Carvalho Chehab 	}
1571786baecfSMauro Carvalho Chehab 
1572786baecfSMauro Carvalho Chehab 	return 0;
1573786baecfSMauro Carvalho Chehab 
1574786baecfSMauro Carvalho Chehab err:
15752b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
1576786baecfSMauro Carvalho Chehab 
1577786baecfSMauro Carvalho Chehab 	return ret;
1578786baecfSMauro Carvalho Chehab }
1579786baecfSMauro Carvalho Chehab 
15805b556084SOlli Salonen static int it930x_tuner_attach(struct dvb_usb_adapter *adap)
15815b556084SOlli Salonen {
15825b556084SOlli Salonen 	struct state *state = adap_to_priv(adap);
15835b556084SOlli Salonen 	struct dvb_usb_device *d = adap_to_d(adap);
15842b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
15855b556084SOlli Salonen 	int ret;
15865b556084SOlli Salonen 	struct si2157_config si2157_config;
15875b556084SOlli Salonen 
15882b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
15895b556084SOlli Salonen 
15905b556084SOlli Salonen 	/* I2C master bus 2 clock speed 300k */
15915b556084SOlli Salonen 	ret = af9035_wr_reg(d, 0x00f6a7, 0x07);
15925b556084SOlli Salonen 	if (ret < 0)
15935b556084SOlli Salonen 		goto err;
15945b556084SOlli Salonen 
15955b556084SOlli Salonen 	/* I2C master bus 1,3 clock speed 300k */
15965b556084SOlli Salonen 	ret = af9035_wr_reg(d, 0x00f103, 0x07);
15975b556084SOlli Salonen 	if (ret < 0)
15985b556084SOlli Salonen 		goto err;
15995b556084SOlli Salonen 
16005b556084SOlli Salonen 	/* set gpio11 low */
16015b556084SOlli Salonen 	ret = af9035_wr_reg_mask(d, 0xd8d4, 0x01, 0x01);
16025b556084SOlli Salonen 	if (ret < 0)
16035b556084SOlli Salonen 		goto err;
16045b556084SOlli Salonen 
16055b556084SOlli Salonen 	ret = af9035_wr_reg_mask(d, 0xd8d5, 0x01, 0x01);
16065b556084SOlli Salonen 	if (ret < 0)
16075b556084SOlli Salonen 		goto err;
16085b556084SOlli Salonen 
16095b556084SOlli Salonen 	ret = af9035_wr_reg_mask(d, 0xd8d3, 0x01, 0x01);
16105b556084SOlli Salonen 	if (ret < 0)
16115b556084SOlli Salonen 		goto err;
16125b556084SOlli Salonen 
16135b556084SOlli Salonen 	/* Tuner enable using gpiot2_en, gpiot2_on and gpiot2_o (reset) */
16145b556084SOlli Salonen 	ret = af9035_wr_reg_mask(d, 0xd8b8, 0x01, 0x01);
16155b556084SOlli Salonen 	if (ret < 0)
16165b556084SOlli Salonen 		goto err;
16175b556084SOlli Salonen 
16185b556084SOlli Salonen 	ret = af9035_wr_reg_mask(d, 0xd8b9, 0x01, 0x01);
16195b556084SOlli Salonen 	if (ret < 0)
16205b556084SOlli Salonen 		goto err;
16215b556084SOlli Salonen 
16225b556084SOlli Salonen 	ret = af9035_wr_reg_mask(d, 0xd8b7, 0x00, 0x01);
16235b556084SOlli Salonen 	if (ret < 0)
16245b556084SOlli Salonen 		goto err;
16255b556084SOlli Salonen 
16265b556084SOlli Salonen 	msleep(200);
16275b556084SOlli Salonen 
16285b556084SOlli Salonen 	ret = af9035_wr_reg_mask(d, 0xd8b7, 0x01, 0x01);
16295b556084SOlli Salonen 	if (ret < 0)
16305b556084SOlli Salonen 		goto err;
16315b556084SOlli Salonen 
16325b556084SOlli Salonen 	memset(&si2157_config, 0, sizeof(si2157_config));
16335b556084SOlli Salonen 	si2157_config.fe = adap->fe[0];
1634ee3c3e46SOlli Salonen 	si2157_config.if_port = 1;
16355b556084SOlli Salonen 	ret = af9035_add_i2c_dev(d, "si2157", 0x63,
16365b556084SOlli Salonen 			&si2157_config, state->i2c_adapter_demod);
16375b556084SOlli Salonen 
16385b556084SOlli Salonen 	if (ret)
16395b556084SOlli Salonen 		goto err;
16405b556084SOlli Salonen 
16415b556084SOlli Salonen 	return 0;
16425b556084SOlli Salonen 
16435b556084SOlli Salonen err:
16442b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
16455b556084SOlli Salonen 
16465b556084SOlli Salonen 	return ret;
16475b556084SOlli Salonen }
16485b556084SOlli Salonen 
16495b556084SOlli Salonen 
16505b556084SOlli Salonen static int it930x_tuner_detach(struct dvb_usb_adapter *adap)
16515b556084SOlli Salonen {
16525b556084SOlli Salonen 	struct state *state = adap_to_priv(adap);
16535b556084SOlli Salonen 	struct dvb_usb_device *d = adap_to_d(adap);
16542b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
16555b556084SOlli Salonen 
16562b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
16575b556084SOlli Salonen 
16585b556084SOlli Salonen 	if (adap->id == 1) {
16595b556084SOlli Salonen 		if (state->i2c_client[3])
16605b556084SOlli Salonen 			af9035_del_i2c_dev(d);
16615b556084SOlli Salonen 	} else if (adap->id == 0) {
16625b556084SOlli Salonen 		if (state->i2c_client[1])
16635b556084SOlli Salonen 			af9035_del_i2c_dev(d);
16645b556084SOlli Salonen 	}
16655b556084SOlli Salonen 
16665b556084SOlli Salonen 	return 0;
16675b556084SOlli Salonen }
16685b556084SOlli Salonen 
16695b556084SOlli Salonen 
1670d4d6a34dSAntti Palosaari static int af9035_tuner_detach(struct dvb_usb_adapter *adap)
1671d4d6a34dSAntti Palosaari {
1672d4d6a34dSAntti Palosaari 	struct state *state = adap_to_priv(adap);
1673d4d6a34dSAntti Palosaari 	struct dvb_usb_device *d = adap_to_d(adap);
16742b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1675d4d6a34dSAntti Palosaari 
16762b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
1677d4d6a34dSAntti Palosaari 
1678d4d6a34dSAntti Palosaari 	switch (state->af9033_config[adap->id].tuner) {
1679b6c5fe70SAntti Palosaari 	case AF9033_TUNER_TUA9001:
16807a893ba9SAntti Palosaari 	case AF9033_TUNER_FC2580:
1681d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_38:
1682d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_51:
1683d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_52:
1684d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_60:
1685d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_61:
1686d4d6a34dSAntti Palosaari 	case AF9033_TUNER_IT9135_62:
1687d4d6a34dSAntti Palosaari 		if (adap->id == 1) {
1688d4d6a34dSAntti Palosaari 			if (state->i2c_client[3])
1689d4d6a34dSAntti Palosaari 				af9035_del_i2c_dev(d);
1690d4d6a34dSAntti Palosaari 		} else if (adap->id == 0) {
1691d4d6a34dSAntti Palosaari 			if (state->i2c_client[1])
1692d4d6a34dSAntti Palosaari 				af9035_del_i2c_dev(d);
1693d4d6a34dSAntti Palosaari 		}
1694d4d6a34dSAntti Palosaari 	}
1695d4d6a34dSAntti Palosaari 
1696d4d6a34dSAntti Palosaari 	return 0;
1697d4d6a34dSAntti Palosaari }
1698d4d6a34dSAntti Palosaari 
1699786baecfSMauro Carvalho Chehab static int af9035_init(struct dvb_usb_device *d)
1700786baecfSMauro Carvalho Chehab {
1701786baecfSMauro Carvalho Chehab 	struct state *state = d_to_priv(d);
17022b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1703786baecfSMauro Carvalho Chehab 	int ret, i;
1704bada342eSAntti Palosaari 	u16 frame_size = (d->udev->speed == USB_SPEED_FULL ? 5 : 87) * 188 / 4;
1705bada342eSAntti Palosaari 	u8 packet_size = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4;
1706786baecfSMauro Carvalho Chehab 	struct reg_val_mask tab[] = {
1707786baecfSMauro Carvalho Chehab 		{ 0x80f99d, 0x01, 0x01 },
1708786baecfSMauro Carvalho Chehab 		{ 0x80f9a4, 0x01, 0x01 },
1709786baecfSMauro Carvalho Chehab 		{ 0x00dd11, 0x00, 0x20 },
1710786baecfSMauro Carvalho Chehab 		{ 0x00dd11, 0x00, 0x40 },
1711786baecfSMauro Carvalho Chehab 		{ 0x00dd13, 0x00, 0x20 },
1712786baecfSMauro Carvalho Chehab 		{ 0x00dd13, 0x00, 0x40 },
1713786baecfSMauro Carvalho Chehab 		{ 0x00dd11, 0x20, 0x20 },
1714786baecfSMauro Carvalho Chehab 		{ 0x00dd88, (frame_size >> 0) & 0xff, 0xff},
1715786baecfSMauro Carvalho Chehab 		{ 0x00dd89, (frame_size >> 8) & 0xff, 0xff},
1716786baecfSMauro Carvalho Chehab 		{ 0x00dd0c, packet_size, 0xff},
1717786baecfSMauro Carvalho Chehab 		{ 0x00dd11, state->dual_mode << 6, 0x40 },
1718786baecfSMauro Carvalho Chehab 		{ 0x00dd8a, (frame_size >> 0) & 0xff, 0xff},
1719786baecfSMauro Carvalho Chehab 		{ 0x00dd8b, (frame_size >> 8) & 0xff, 0xff},
1720786baecfSMauro Carvalho Chehab 		{ 0x00dd0d, packet_size, 0xff },
17219805992fSJose Alberto Reguero 		{ 0x80f9a3, state->dual_mode, 0x01 },
17229805992fSJose Alberto Reguero 		{ 0x80f9cd, state->dual_mode, 0x01 },
1723786baecfSMauro Carvalho Chehab 		{ 0x80f99d, 0x00, 0x01 },
1724786baecfSMauro Carvalho Chehab 		{ 0x80f9a4, 0x00, 0x01 },
1725786baecfSMauro Carvalho Chehab 	};
1726786baecfSMauro Carvalho Chehab 
17272b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "USB speed=%d frame_size=%04x packet_size=%02x\n",
17282b987ea7SAntti Palosaari 		d->udev->speed, frame_size, packet_size);
1729786baecfSMauro Carvalho Chehab 
1730786baecfSMauro Carvalho Chehab 	/* init endpoints */
1731786baecfSMauro Carvalho Chehab 	for (i = 0; i < ARRAY_SIZE(tab); i++) {
1732786baecfSMauro Carvalho Chehab 		ret = af9035_wr_reg_mask(d, tab[i].reg, tab[i].val,
1733786baecfSMauro Carvalho Chehab 				tab[i].mask);
1734786baecfSMauro Carvalho Chehab 		if (ret < 0)
1735786baecfSMauro Carvalho Chehab 			goto err;
1736786baecfSMauro Carvalho Chehab 	}
1737786baecfSMauro Carvalho Chehab 
1738786baecfSMauro Carvalho Chehab 	return 0;
1739786baecfSMauro Carvalho Chehab 
1740786baecfSMauro Carvalho Chehab err:
17412b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
1742786baecfSMauro Carvalho Chehab 
1743786baecfSMauro Carvalho Chehab 	return ret;
1744786baecfSMauro Carvalho Chehab }
1745786baecfSMauro Carvalho Chehab 
17465b556084SOlli Salonen static int it930x_init(struct dvb_usb_device *d)
17475b556084SOlli Salonen {
17485b556084SOlli Salonen 	struct state *state = d_to_priv(d);
17492b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
17505b556084SOlli Salonen 	int ret, i;
17515b556084SOlli Salonen 	u16 frame_size = (d->udev->speed == USB_SPEED_FULL ? 5 : 816) * 188 / 4;
17525b556084SOlli Salonen 	u8 packet_size = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4;
17535b556084SOlli Salonen 	struct reg_val_mask tab[] = {
17545b556084SOlli Salonen 		{ 0x00da1a, 0x00, 0x01 }, /* ignore_sync_byte */
17555b556084SOlli Salonen 		{ 0x00f41f, 0x04, 0x04 }, /* dvbt_inten */
17565b556084SOlli Salonen 		{ 0x00da10, 0x00, 0x01 }, /* mpeg_full_speed */
17575b556084SOlli Salonen 		{ 0x00f41a, 0x01, 0x01 }, /* dvbt_en */
17585b556084SOlli Salonen 		{ 0x00da1d, 0x01, 0x01 }, /* mp2_sw_rst, reset EP4 */
17595b556084SOlli Salonen 		{ 0x00dd11, 0x00, 0x20 }, /* ep4_tx_en, disable EP4 */
17605b556084SOlli Salonen 		{ 0x00dd13, 0x00, 0x20 }, /* ep4_tx_nak, disable EP4 NAK */
17615b556084SOlli Salonen 		{ 0x00dd11, 0x20, 0x20 }, /* ep4_tx_en, enable EP4 */
17625b556084SOlli Salonen 		{ 0x00dd11, 0x00, 0x40 }, /* ep5_tx_en, disable EP5 */
17635b556084SOlli Salonen 		{ 0x00dd13, 0x00, 0x40 }, /* ep5_tx_nak, disable EP5 NAK */
17645b556084SOlli Salonen 		{ 0x00dd11, state->dual_mode << 6, 0x40 }, /* enable EP5 */
17655b556084SOlli Salonen 		{ 0x00dd88, (frame_size >> 0) & 0xff, 0xff},
17665b556084SOlli Salonen 		{ 0x00dd89, (frame_size >> 8) & 0xff, 0xff},
17675b556084SOlli Salonen 		{ 0x00dd0c, packet_size, 0xff},
17685b556084SOlli Salonen 		{ 0x00dd8a, (frame_size >> 0) & 0xff, 0xff},
17695b556084SOlli Salonen 		{ 0x00dd8b, (frame_size >> 8) & 0xff, 0xff},
17705b556084SOlli Salonen 		{ 0x00dd0d, packet_size, 0xff },
17715b556084SOlli Salonen 		{ 0x00da1d, 0x00, 0x01 }, /* mp2_sw_rst, disable */
17725b556084SOlli Salonen 		{ 0x00d833, 0x01, 0xff }, /* slew rate ctrl: slew rate boosts */
17735b556084SOlli Salonen 		{ 0x00d830, 0x00, 0xff }, /* Bit 0 of output driving control */
17745b556084SOlli Salonen 		{ 0x00d831, 0x01, 0xff }, /* Bit 1 of output driving control */
17755b556084SOlli Salonen 		{ 0x00d832, 0x00, 0xff }, /* Bit 2 of output driving control */
17765b556084SOlli Salonen 
17775b556084SOlli Salonen 		/* suspend gpio1 for TS-C */
17785b556084SOlli Salonen 		{ 0x00d8b0, 0x01, 0xff }, /* gpio1 */
17795b556084SOlli Salonen 		{ 0x00d8b1, 0x01, 0xff }, /* gpio1 */
17805b556084SOlli Salonen 		{ 0x00d8af, 0x00, 0xff }, /* gpio1 */
17815b556084SOlli Salonen 
17825b556084SOlli Salonen 		/* suspend gpio7 for TS-D */
17835b556084SOlli Salonen 		{ 0x00d8c4, 0x01, 0xff }, /* gpio7 */
17845b556084SOlli Salonen 		{ 0x00d8c5, 0x01, 0xff }, /* gpio7 */
17855b556084SOlli Salonen 		{ 0x00d8c3, 0x00, 0xff }, /* gpio7 */
17865b556084SOlli Salonen 
17875b556084SOlli Salonen 		/* suspend gpio13 for TS-B */
17885b556084SOlli Salonen 		{ 0x00d8dc, 0x01, 0xff }, /* gpio13 */
17895b556084SOlli Salonen 		{ 0x00d8dd, 0x01, 0xff }, /* gpio13 */
17905b556084SOlli Salonen 		{ 0x00d8db, 0x00, 0xff }, /* gpio13 */
17915b556084SOlli Salonen 
17925b556084SOlli Salonen 		/* suspend gpio14 for TS-E */
17935b556084SOlli Salonen 		{ 0x00d8e4, 0x01, 0xff }, /* gpio14 */
17945b556084SOlli Salonen 		{ 0x00d8e5, 0x01, 0xff }, /* gpio14 */
17955b556084SOlli Salonen 		{ 0x00d8e3, 0x00, 0xff }, /* gpio14 */
17965b556084SOlli Salonen 
17975b556084SOlli Salonen 		/* suspend gpio15 for TS-A */
17985b556084SOlli Salonen 		{ 0x00d8e8, 0x01, 0xff }, /* gpio15 */
17995b556084SOlli Salonen 		{ 0x00d8e9, 0x01, 0xff }, /* gpio15 */
18005b556084SOlli Salonen 		{ 0x00d8e7, 0x00, 0xff }, /* gpio15 */
18015b556084SOlli Salonen 
18025b556084SOlli Salonen 		{ 0x00da58, 0x00, 0x01 }, /* ts_in_src, serial */
18035b556084SOlli Salonen 		{ 0x00da73, 0x01, 0xff }, /* ts0_aggre_mode */
18045b556084SOlli Salonen 		{ 0x00da78, 0x47, 0xff }, /* ts0_sync_byte */
18055b556084SOlli Salonen 		{ 0x00da4c, 0x01, 0xff }, /* ts0_en */
18065b556084SOlli Salonen 		{ 0x00da5a, 0x1f, 0xff }, /* ts_fail_ignore */
18075b556084SOlli Salonen 	};
18085b556084SOlli Salonen 
18092b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "USB speed=%d frame_size=%04x packet_size=%02x\n",
18102b987ea7SAntti Palosaari 		d->udev->speed, frame_size, packet_size);
18115b556084SOlli Salonen 
18125b556084SOlli Salonen 	/* init endpoints */
18135b556084SOlli Salonen 	for (i = 0; i < ARRAY_SIZE(tab); i++) {
18145b556084SOlli Salonen 		ret = af9035_wr_reg_mask(d, tab[i].reg,
18155b556084SOlli Salonen 				tab[i].val, tab[i].mask);
18165b556084SOlli Salonen 
18175b556084SOlli Salonen 		if (ret < 0)
18185b556084SOlli Salonen 			goto err;
18195b556084SOlli Salonen 	}
18205b556084SOlli Salonen 
18215b556084SOlli Salonen 	return 0;
18225b556084SOlli Salonen err:
18232b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
18245b556084SOlli Salonen 
18255b556084SOlli Salonen 	return ret;
18265b556084SOlli Salonen }
18275b556084SOlli Salonen 
18285b556084SOlli Salonen 
182937b44a0fSAntti Palosaari #if IS_ENABLED(CONFIG_RC_CORE)
1830786baecfSMauro Carvalho Chehab static int af9035_rc_query(struct dvb_usb_device *d)
1831786baecfSMauro Carvalho Chehab {
18322b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1833786baecfSMauro Carvalho Chehab 	int ret;
18342ceeca04SSean Young 	enum rc_type proto;
183575cd5886SAntti Palosaari 	u32 key;
183675cd5886SAntti Palosaari 	u8 buf[4];
183775cd5886SAntti Palosaari 	struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, buf };
1838786baecfSMauro Carvalho Chehab 
1839786baecfSMauro Carvalho Chehab 	ret = af9035_ctrl_msg(d, &req);
18401bfd5294SAntti Palosaari 	if (ret == 1)
18411bfd5294SAntti Palosaari 		return 0;
18421bfd5294SAntti Palosaari 	else if (ret < 0)
1843786baecfSMauro Carvalho Chehab 		goto err;
1844786baecfSMauro Carvalho Chehab 
184575cd5886SAntti Palosaari 	if ((buf[2] + buf[3]) == 0xff) {
184675cd5886SAntti Palosaari 		if ((buf[0] + buf[1]) == 0xff) {
184775cd5886SAntti Palosaari 			/* NEC standard 16bit */
1848120703f9SDavid Härdeman 			key = RC_SCANCODE_NEC(buf[0], buf[2]);
18492ceeca04SSean Young 			proto = RC_TYPE_NEC;
1850786baecfSMauro Carvalho Chehab 		} else {
185175cd5886SAntti Palosaari 			/* NEC extended 24bit */
1852120703f9SDavid Härdeman 			key = RC_SCANCODE_NECX(buf[0] << 8 | buf[1], buf[2]);
18532ceeca04SSean Young 			proto = RC_TYPE_NECX;
1854786baecfSMauro Carvalho Chehab 		}
1855786baecfSMauro Carvalho Chehab 	} else {
185675cd5886SAntti Palosaari 		/* NEC full code 32bit */
1857120703f9SDavid Härdeman 		key = RC_SCANCODE_NEC32(buf[0] << 24 | buf[1] << 16 |
1858120703f9SDavid Härdeman 					buf[2] << 8  | buf[3]);
18592ceeca04SSean Young 		proto = RC_TYPE_NEC32;
1860786baecfSMauro Carvalho Chehab 	}
1861786baecfSMauro Carvalho Chehab 
18622b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "%*ph\n", 4, buf);
186375cd5886SAntti Palosaari 
18642ceeca04SSean Young 	rc_keydown(d->rc_dev, proto, key, 0);
1865786baecfSMauro Carvalho Chehab 
1866786baecfSMauro Carvalho Chehab 	return 0;
18671bfd5294SAntti Palosaari 
18681bfd5294SAntti Palosaari err:
18692b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "failed=%d\n", ret);
18701bfd5294SAntti Palosaari 
18711bfd5294SAntti Palosaari 	return ret;
1872786baecfSMauro Carvalho Chehab }
1873786baecfSMauro Carvalho Chehab 
1874786baecfSMauro Carvalho Chehab static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
1875786baecfSMauro Carvalho Chehab {
187674c1883aSAntti Palosaari 	struct state *state = d_to_priv(d);
18772b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1878786baecfSMauro Carvalho Chehab 
187909bfd96cSAntti Palosaari 	dev_dbg(&intf->dev, "ir_mode=%02x ir_type=%02x\n",
188009bfd96cSAntti Palosaari 		state->ir_mode, state->ir_type);
1881786baecfSMauro Carvalho Chehab 
1882786baecfSMauro Carvalho Chehab 	/* don't activate rc if in HID mode or if not available */
188309bfd96cSAntti Palosaari 	if (state->ir_mode == 0x05) {
188409bfd96cSAntti Palosaari 		switch (state->ir_type) {
1885786baecfSMauro Carvalho Chehab 		case 0: /* NEC */
1886786baecfSMauro Carvalho Chehab 		default:
18872ceeca04SSean Young 			rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX |
18882ceeca04SSean Young 								RC_BIT_NEC32;
1889786baecfSMauro Carvalho Chehab 			break;
1890786baecfSMauro Carvalho Chehab 		case 1: /* RC6 */
1891c003ab1bSDavid Härdeman 			rc->allowed_protos = RC_BIT_RC6_MCE;
1892786baecfSMauro Carvalho Chehab 			break;
1893786baecfSMauro Carvalho Chehab 		}
1894786baecfSMauro Carvalho Chehab 
1895786baecfSMauro Carvalho Chehab 		rc->query = af9035_rc_query;
1896786baecfSMauro Carvalho Chehab 		rc->interval = 500;
1897786baecfSMauro Carvalho Chehab 
1898786baecfSMauro Carvalho Chehab 		/* load empty to enable rc */
1899786baecfSMauro Carvalho Chehab 		if (!rc->map_name)
1900786baecfSMauro Carvalho Chehab 			rc->map_name = RC_MAP_EMPTY;
1901786baecfSMauro Carvalho Chehab 	}
1902786baecfSMauro Carvalho Chehab 
1903786baecfSMauro Carvalho Chehab 	return 0;
1904786baecfSMauro Carvalho Chehab }
1905eed5670aSAntti Palosaari #else
1906eed5670aSAntti Palosaari 	#define af9035_get_rc_config NULL
1907eed5670aSAntti Palosaari #endif
1908786baecfSMauro Carvalho Chehab 
1909bada342eSAntti Palosaari static int af9035_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
1910bada342eSAntti Palosaari 		struct usb_data_stream_properties *stream)
1911bada342eSAntti Palosaari {
1912bada342eSAntti Palosaari 	struct dvb_usb_device *d = fe_to_d(fe);
19132b987ea7SAntti Palosaari 	struct usb_interface *intf = d->intf;
1914c10989a2SAntti Palosaari 
19152b987ea7SAntti Palosaari 	dev_dbg(&intf->dev, "adap=%d\n", fe_to_adap(fe)->id);
1916bada342eSAntti Palosaari 
1917bada342eSAntti Palosaari 	if (d->udev->speed == USB_SPEED_FULL)
1918bada342eSAntti Palosaari 		stream->u.bulk.buffersize = 5 * 188;
1919bada342eSAntti Palosaari 
1920bada342eSAntti Palosaari 	return 0;
1921bada342eSAntti Palosaari }
1922bada342eSAntti Palosaari 
1923bada342eSAntti Palosaari static int af9035_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
1924bada342eSAntti Palosaari {
1925ed97a6feSMauro Carvalho Chehab 	struct state *state = adap_to_priv(adap);
1926ed97a6feSMauro Carvalho Chehab 
1927ed97a6feSMauro Carvalho Chehab 	return state->ops.pid_filter_ctrl(adap->fe[0], onoff);
1928bada342eSAntti Palosaari }
1929bada342eSAntti Palosaari 
1930bada342eSAntti Palosaari static int af9035_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
1931bada342eSAntti Palosaari 		int onoff)
1932bada342eSAntti Palosaari {
1933ed97a6feSMauro Carvalho Chehab 	struct state *state = adap_to_priv(adap);
1934ed97a6feSMauro Carvalho Chehab 
1935ed97a6feSMauro Carvalho Chehab 	return state->ops.pid_filter(adap->fe[0], index, pid, onoff);
1936bada342eSAntti Palosaari }
1937bada342eSAntti Palosaari 
1938b799b810SAntti Palosaari static int af9035_probe(struct usb_interface *intf,
1939b799b810SAntti Palosaari 		const struct usb_device_id *id)
1940b799b810SAntti Palosaari {
1941b799b810SAntti Palosaari 	struct usb_device *udev = interface_to_usbdev(intf);
1942b799b810SAntti Palosaari 	char manufacturer[sizeof("Afatech")];
1943b799b810SAntti Palosaari 
1944b799b810SAntti Palosaari 	memset(manufacturer, 0, sizeof(manufacturer));
1945b799b810SAntti Palosaari 	usb_string(udev, udev->descriptor.iManufacturer,
1946b799b810SAntti Palosaari 			manufacturer, sizeof(manufacturer));
1947b799b810SAntti Palosaari 	/*
1948b799b810SAntti Palosaari 	 * There is two devices having same ID but different chipset. One uses
1949b799b810SAntti Palosaari 	 * AF9015 and the other IT9135 chipset. Only difference seen on lsusb
1950b799b810SAntti Palosaari 	 * is iManufacturer string.
1951b799b810SAntti Palosaari 	 *
1952b799b810SAntti Palosaari 	 * idVendor           0x0ccd TerraTec Electronic GmbH
1953b799b810SAntti Palosaari 	 * idProduct          0x0099
1954b799b810SAntti Palosaari 	 * bcdDevice            2.00
1955b799b810SAntti Palosaari 	 * iManufacturer           1 Afatech
1956b799b810SAntti Palosaari 	 * iProduct                2 DVB-T 2
1957b799b810SAntti Palosaari 	 *
1958b799b810SAntti Palosaari 	 * idVendor           0x0ccd TerraTec Electronic GmbH
1959b799b810SAntti Palosaari 	 * idProduct          0x0099
1960b799b810SAntti Palosaari 	 * bcdDevice            2.00
1961b799b810SAntti Palosaari 	 * iManufacturer           1 ITE Technologies, Inc.
1962b799b810SAntti Palosaari 	 * iProduct                2 DVB-T TV Stick
1963b799b810SAntti Palosaari 	 */
1964b799b810SAntti Palosaari 	if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VID_TERRATEC) &&
1965b799b810SAntti Palosaari 			(le16_to_cpu(udev->descriptor.idProduct) == 0x0099)) {
1966b799b810SAntti Palosaari 		if (!strcmp("Afatech", manufacturer)) {
19672b987ea7SAntti Palosaari 			dev_dbg(&udev->dev, "rejecting device\n");
1968b799b810SAntti Palosaari 			return -ENODEV;
1969b799b810SAntti Palosaari 		}
1970b799b810SAntti Palosaari 	}
1971b799b810SAntti Palosaari 
1972b799b810SAntti Palosaari 	return dvb_usbv2_probe(intf, id);
1973b799b810SAntti Palosaari }
1974b799b810SAntti Palosaari 
1975786baecfSMauro Carvalho Chehab /* interface 0 is used by DVB-T receiver and
1976786baecfSMauro Carvalho Chehab    interface 1 is for remote controller (HID) */
1977786baecfSMauro Carvalho Chehab static const struct dvb_usb_device_properties af9035_props = {
1978786baecfSMauro Carvalho Chehab 	.driver_name = KBUILD_MODNAME,
1979786baecfSMauro Carvalho Chehab 	.owner = THIS_MODULE,
1980786baecfSMauro Carvalho Chehab 	.adapter_nr = adapter_nr,
1981786baecfSMauro Carvalho Chehab 	.size_of_priv = sizeof(struct state),
1982786baecfSMauro Carvalho Chehab 
1983786baecfSMauro Carvalho Chehab 	.generic_bulk_ctrl_endpoint = 0x02,
1984786baecfSMauro Carvalho Chehab 	.generic_bulk_ctrl_endpoint_response = 0x81,
1985786baecfSMauro Carvalho Chehab 
1986786baecfSMauro Carvalho Chehab 	.identify_state = af9035_identify_state,
1987786baecfSMauro Carvalho Chehab 	.download_firmware = af9035_download_firmware,
1988786baecfSMauro Carvalho Chehab 
1989786baecfSMauro Carvalho Chehab 	.i2c_algo = &af9035_i2c_algo,
1990786baecfSMauro Carvalho Chehab 	.read_config = af9035_read_config,
1991786baecfSMauro Carvalho Chehab 	.frontend_attach = af9035_frontend_attach,
1992d4d6a34dSAntti Palosaari 	.frontend_detach = af9035_frontend_detach,
1993786baecfSMauro Carvalho Chehab 	.tuner_attach = af9035_tuner_attach,
1994d4d6a34dSAntti Palosaari 	.tuner_detach = af9035_tuner_detach,
1995786baecfSMauro Carvalho Chehab 	.init = af9035_init,
1996786baecfSMauro Carvalho Chehab 	.get_rc_config = af9035_get_rc_config,
1997bada342eSAntti Palosaari 	.get_stream_config = af9035_get_stream_config,
1998786baecfSMauro Carvalho Chehab 
19999805992fSJose Alberto Reguero 	.get_adapter_count = af9035_get_adapter_count,
2000786baecfSMauro Carvalho Chehab 	.adapter = {
2001786baecfSMauro Carvalho Chehab 		{
2002bada342eSAntti Palosaari 			.caps = DVB_USB_ADAP_HAS_PID_FILTER |
2003bada342eSAntti Palosaari 				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2004bada342eSAntti Palosaari 
2005bada342eSAntti Palosaari 			.pid_filter_count = 32,
2006bada342eSAntti Palosaari 			.pid_filter_ctrl = af9035_pid_filter_ctrl,
2007bada342eSAntti Palosaari 			.pid_filter = af9035_pid_filter,
2008bada342eSAntti Palosaari 
2009786baecfSMauro Carvalho Chehab 			.stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
2010786baecfSMauro Carvalho Chehab 		}, {
2011b24c2b4fSAntti Palosaari 			.caps = DVB_USB_ADAP_HAS_PID_FILTER |
2012b24c2b4fSAntti Palosaari 				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2013b24c2b4fSAntti Palosaari 
2014b24c2b4fSAntti Palosaari 			.pid_filter_count = 32,
2015b24c2b4fSAntti Palosaari 			.pid_filter_ctrl = af9035_pid_filter_ctrl,
2016b24c2b4fSAntti Palosaari 			.pid_filter = af9035_pid_filter,
2017b24c2b4fSAntti Palosaari 
2018786baecfSMauro Carvalho Chehab 			.stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
2019786baecfSMauro Carvalho Chehab 		},
2020786baecfSMauro Carvalho Chehab 	},
2021786baecfSMauro Carvalho Chehab };
2022786baecfSMauro Carvalho Chehab 
20235b556084SOlli Salonen static const struct dvb_usb_device_properties it930x_props = {
20245b556084SOlli Salonen 	.driver_name = KBUILD_MODNAME,
20255b556084SOlli Salonen 	.owner = THIS_MODULE,
20265b556084SOlli Salonen 	.adapter_nr = adapter_nr,
20275b556084SOlli Salonen 	.size_of_priv = sizeof(struct state),
20285b556084SOlli Salonen 
20295b556084SOlli Salonen 	.generic_bulk_ctrl_endpoint = 0x02,
20305b556084SOlli Salonen 	.generic_bulk_ctrl_endpoint_response = 0x81,
20315b556084SOlli Salonen 
20325b556084SOlli Salonen 	.identify_state = af9035_identify_state,
20335b556084SOlli Salonen 	.download_firmware = af9035_download_firmware,
20345b556084SOlli Salonen 
20355b556084SOlli Salonen 	.i2c_algo = &af9035_i2c_algo,
20365b556084SOlli Salonen 	.read_config = af9035_read_config,
20375b556084SOlli Salonen 	.frontend_attach = it930x_frontend_attach,
20385b556084SOlli Salonen 	.frontend_detach = af9035_frontend_detach,
20395b556084SOlli Salonen 	.tuner_attach = it930x_tuner_attach,
20405b556084SOlli Salonen 	.tuner_detach = it930x_tuner_detach,
20415b556084SOlli Salonen 	.init = it930x_init,
20425b556084SOlli Salonen 	.get_stream_config = af9035_get_stream_config,
20435b556084SOlli Salonen 
20445b556084SOlli Salonen 	.get_adapter_count = af9035_get_adapter_count,
20455b556084SOlli Salonen 	.adapter = {
20465b556084SOlli Salonen 		{
20475b556084SOlli Salonen 			.stream = DVB_USB_STREAM_BULK(0x84, 4, 816 * 188),
20485b556084SOlli Salonen 		}, {
20495b556084SOlli Salonen 			.stream = DVB_USB_STREAM_BULK(0x85, 4, 816 * 188),
20505b556084SOlli Salonen 		},
20515b556084SOlli Salonen 	},
20525b556084SOlli Salonen };
20535b556084SOlli Salonen 
2054786baecfSMauro Carvalho Chehab static const struct usb_device_id af9035_id_table[] = {
2055bc3c9e10SAntti Palosaari 	/* AF9035 devices */
2056786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035,
2057786baecfSMauro Carvalho Chehab 		&af9035_props, "Afatech AF9035 reference design", NULL) },
2058786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1000,
2059786baecfSMauro Carvalho Chehab 		&af9035_props, "Afatech AF9035 reference design", NULL) },
2060786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1001,
2061786baecfSMauro Carvalho Chehab 		&af9035_props, "Afatech AF9035 reference design", NULL) },
2062786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1002,
2063786baecfSMauro Carvalho Chehab 		&af9035_props, "Afatech AF9035 reference design", NULL) },
2064786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1003,
2065786baecfSMauro Carvalho Chehab 		&af9035_props, "Afatech AF9035 reference design", NULL) },
2066786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK,
2067786baecfSMauro Carvalho Chehab 		&af9035_props, "TerraTec Cinergy T Stick", NULL) },
2068786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835,
2069786baecfSMauro Carvalho Chehab 		&af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
2070786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_B835,
2071786baecfSMauro Carvalho Chehab 		&af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
2072786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_1867,
2073786baecfSMauro Carvalho Chehab 		&af9035_props, "AVerMedia HD Volar (A867)", NULL) },
2074786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A867,
2075786baecfSMauro Carvalho Chehab 		&af9035_props, "AVerMedia HD Volar (A867)", NULL) },
2076786baecfSMauro Carvalho Chehab 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TWINSTAR,
2077786baecfSMauro Carvalho Chehab 		&af9035_props, "AVerMedia Twinstar (A825)", NULL) },
2078d67ceb33SOliver Schinagl 	{ DVB_USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100MINI_PLUS,
2079d67ceb33SOliver Schinagl 		&af9035_props, "Asus U3100Mini Plus", NULL) },
2080d9b7595bSFabrizio Gazzato 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, 0x00aa,
2081d9b7595bSFabrizio Gazzato 		&af9035_props, "TerraTec Cinergy T Stick (rev. 2)", NULL) },
2082baf06b51SAntti Palosaari 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, 0x0337,
2083baf06b51SAntti Palosaari 		&af9035_props, "AVerMedia HD Volar (A867)", NULL) },
208437e78568SCIJOML CIJOMLovic        { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_EVOLVEO_XTRATV_STICK,
208537e78568SCIJOML CIJOMLovic 	       &af9035_props, "EVOLVEO XtraTV stick", NULL) },
2086b3f02270SAntti Palosaari 
2087bc3c9e10SAntti Palosaari 	/* IT9135 devices */
20887a541ce0SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135,
20897a541ce0SMalcolm Priestley 		&af9035_props, "ITE 9135 Generic", RC_MAP_IT913X_V1) },
20907a541ce0SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005,
20917a541ce0SMalcolm Priestley 		&af9035_props, "ITE 9135(9005) Generic", RC_MAP_IT913X_V2) },
20927a541ce0SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006,
20937a541ce0SMalcolm Priestley 		&af9035_props, "ITE 9135(9006) Generic", RC_MAP_IT913X_V1) },
20947a541ce0SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_1835,
20957a541ce0SMalcolm Priestley 		&af9035_props, "Avermedia A835B(1835)", RC_MAP_IT913X_V2) },
20967a541ce0SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_2835,
20977a541ce0SMalcolm Priestley 		&af9035_props, "Avermedia A835B(2835)", RC_MAP_IT913X_V2) },
20987a541ce0SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_3835,
20997a541ce0SMalcolm Priestley 		&af9035_props, "Avermedia A835B(3835)", RC_MAP_IT913X_V2) },
21007a541ce0SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835B_4835,
21017a541ce0SMalcolm Priestley 		&af9035_props, "Avermedia A835B(4835)",	RC_MAP_IT913X_V2) },
2102b8ebfafcSPhilippe Valembois 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TD110,
2103b8ebfafcSPhilippe Valembois 		&af9035_props, "Avermedia AverTV Volar HD 2 (TD110)", RC_MAP_AVERMEDIA_RM_KS) },
21047a541ce0SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_H335,
21057a541ce0SMalcolm Priestley 		&af9035_props, "Avermedia H335", RC_MAP_IT913X_V2) },
210637973e01SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09,
210737973e01SMalcolm Priestley 		&af9035_props, "Kworld UB499-2T T09", RC_MAP_IT913X_V1) },
210837973e01SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137,
210937973e01SMalcolm Priestley 		&af9035_props, "Sveon STV22 Dual DVB-T HDTV",
211037973e01SMalcolm Priestley 							RC_MAP_IT913X_V1) },
211137973e01SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CTVDIGDUAL_V2,
211237973e01SMalcolm Priestley 		&af9035_props, "Digital Dual TV Receiver CTVDIGDUAL_V2",
211337973e01SMalcolm Priestley 							RC_MAP_IT913X_V1) },
2114b799b810SAntti Palosaari 	/* XXX: that same ID [0ccd:0099] is used by af9015 driver too */
2115b799b810SAntti Palosaari 	{ DVB_USB_DEVICE(USB_VID_TERRATEC, 0x0099,
2116c10989a2SAntti Palosaari 		&af9035_props, "TerraTec Cinergy T Stick Dual RC (rev. 2)",
2117c10989a2SAntti Palosaari 		NULL) },
21180c413d10SAntti Palosaari 	{ DVB_USB_DEVICE(USB_VID_LEADTEK, 0x6a05,
21190c413d10SAntti Palosaari 		&af9035_props, "Leadtek WinFast DTV Dongle Dual", NULL) },
2120261cb200SAntti Palosaari 	{ DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xf900,
2121261cb200SAntti Palosaari 		&af9035_props, "Hauppauge WinTV-MiniStick 2", NULL) },
2122a04646c0SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_78E,
21235c114a4fSAntti Palosaari 		&af9035_props, "PCTV AndroiDTV (78e)", RC_MAP_IT913X_V1) },
2124a04646c0SMalcolm Priestley 	{ DVB_USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_79E,
21255c114a4fSAntti Palosaari 		&af9035_props, "PCTV microStick (79e)", RC_MAP_IT913X_V2) },
2126b3f02270SAntti Palosaari 
2127b3f02270SAntti Palosaari 	/* IT930x devices */
2128b3f02270SAntti Palosaari 	{ DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9303,
2129b3f02270SAntti Palosaari 		&it930x_props, "ITE 9303 Generic", NULL) },
2130786baecfSMauro Carvalho Chehab 	{ }
2131786baecfSMauro Carvalho Chehab };
2132786baecfSMauro Carvalho Chehab MODULE_DEVICE_TABLE(usb, af9035_id_table);
2133786baecfSMauro Carvalho Chehab 
2134786baecfSMauro Carvalho Chehab static struct usb_driver af9035_usb_driver = {
2135786baecfSMauro Carvalho Chehab 	.name = KBUILD_MODNAME,
2136786baecfSMauro Carvalho Chehab 	.id_table = af9035_id_table,
2137b799b810SAntti Palosaari 	.probe = af9035_probe,
2138786baecfSMauro Carvalho Chehab 	.disconnect = dvb_usbv2_disconnect,
2139786baecfSMauro Carvalho Chehab 	.suspend = dvb_usbv2_suspend,
2140786baecfSMauro Carvalho Chehab 	.resume = dvb_usbv2_resume,
214104966aa8SAntti Palosaari 	.reset_resume = dvb_usbv2_reset_resume,
2142786baecfSMauro Carvalho Chehab 	.no_dynamic_id = 1,
2143786baecfSMauro Carvalho Chehab 	.soft_unbind = 1,
2144786baecfSMauro Carvalho Chehab };
2145786baecfSMauro Carvalho Chehab 
2146786baecfSMauro Carvalho Chehab module_usb_driver(af9035_usb_driver);
2147786baecfSMauro Carvalho Chehab 
2148786baecfSMauro Carvalho Chehab MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
2149786baecfSMauro Carvalho Chehab MODULE_DESCRIPTION("Afatech AF9035 driver");
2150786baecfSMauro Carvalho Chehab MODULE_LICENSE("GPL");
21514395e4b7SAntti Palosaari MODULE_FIRMWARE(AF9035_FIRMWARE_AF9035);
215274c1883aSAntti Palosaari MODULE_FIRMWARE(AF9035_FIRMWARE_IT9135_V1);
215374c1883aSAntti Palosaari MODULE_FIRMWARE(AF9035_FIRMWARE_IT9135_V2);
21545b556084SOlli Salonen MODULE_FIRMWARE(AF9035_FIRMWARE_IT9303);
2155