anysee.c revision 52b661449aecc47e652a164c0d8078b31e10aca0
1a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari/*
2a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
3a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *
4a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *
6a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    This program is free software; you can redistribute it and/or modify
7a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    it under the terms of the GNU General Public License as published by
8a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    the Free Software Foundation; either version 2 of the License, or
9a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    (at your option) any later version.
10a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *
11a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    This program is distributed in the hope that it will be useful,
12a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    GNU General Public License for more details.
15a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *
16a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    You should have received a copy of the GNU General Public License
17a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    along with this program; if not, write to the Free Software
18a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *
20a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari * TODO:
21a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari * - add smart card reader support for Conditional Access (CA)
22a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *
23a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari * Card reader in Anysee is nothing more than ISO 7816 card reader.
24a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari * There is no hardware CAM in any Anysee device sold.
25a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari * In my understanding it should be implemented by making own module
269fdd9caf44296213c1e1130e86c2f919f83124daAntti Palosaari * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
279fdd9caf44296213c1e1130e86c2f919f83124daAntti Palosaari * module registers serial interface that can be used to communicate
28a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari * with any ISO 7816 smart card.
29a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari *
30a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari * Any help according to implement serial smart card reader support
31a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari * is highly welcome!
32a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari */
33a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
34a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari#include "anysee.h"
35a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari#include "tda1002x.h"
36a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari#include "mt352.h"
37a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari#include "mt352_priv.h"
38a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari#include "zl10353.h"
39a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
40a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari/* debug */
41a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int dvb_usb_anysee_debug;
42a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaarimodule_param_named(debug, dvb_usb_anysee_debug, int, 0644);
43a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti PalosaariMODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
44ffbc5f88148ff77039a4269e3f945e8471b2e0bbMauro Carvalho Chehabstatic int dvb_usb_anysee_delsys;
450f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaarimodule_param_named(delsys, dvb_usb_anysee_delsys, int, 0644);
460f77c3a4880f33127bc8d593e0e466f004a4addeAntti PalosaariMODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)");
47a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti PalosaariDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
48a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
49dec0c46ac2af9bbc4a2acd56e5bffbf02f20113eAkinobu Mitastatic DEFINE_MUTEX(anysee_usb_mutex);
50a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
51a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
52a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 *rbuf, u8 rlen)
53a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
54a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	struct anysee_state *state = d->priv;
55a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	int act_len, ret;
56a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 buf[64];
57a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
58a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (slen > sizeof(buf))
59a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		slen = sizeof(buf);
60a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	memcpy(&buf[0], sbuf, slen);
61a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	buf[60] = state->seq++;
62a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
63a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)
64a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return -EAGAIN;
65a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
66a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* We need receive one message more after dvb_usb_generic_rw due
67a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	   to weird transaction flow, which is 1 x send + 2 x receive. */
68a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
69a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
70a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (!ret) {
71a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		/* receive 2nd answer */
72a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
73a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
74a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			&act_len, 2000);
75a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		if (ret)
76a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			err("%s: recv bulk message failed: %d", __func__, ret);
77a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		else {
78a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			deb_xfer("<<< ");
79a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			debug_dump(buf, act_len, deb_xfer);
80a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		}
81a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	}
82a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
83a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* read request, copy returned data to return buf */
84a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (!ret && rbuf && rlen)
85a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		memcpy(rbuf, buf, rlen);
86a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
87a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	mutex_unlock(&anysee_usb_mutex);
88a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
89a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return ret;
90a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
91a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
92a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
93a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
94a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
95a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	int ret;
96a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
97a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
98a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return ret;
99a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
100a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
101a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
102a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
103a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
104a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
105a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
106a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
107a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
108a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
109a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
110a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 buf[] = {CMD_GET_HW_INFO};
111a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
112a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
113a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
114a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
115a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
116a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
117a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	deb_info("%s: onoff:%02x\n", __func__, onoff);
118a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0);
119a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
120a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
121a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
122a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
123a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
124a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
125a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
126a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
127a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
128a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
129a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
130a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
131a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	deb_info("%s: onoff:%02x\n", __func__, onoff);
132a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
133a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
134a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
135a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_init(struct dvb_usb_device *d)
136a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
137a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	int ret;
138a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* LED light */
139a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = anysee_led_ctrl(d, 0x01, 0x03);
140a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
141a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return ret;
142a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
143a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* enable IR */
144a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = anysee_ir_ctrl(d, 1);
145a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
146a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return ret;
147a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
148a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return 0;
149a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
150a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
151a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari/* I2C */
152a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
153a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	int num)
154a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
155a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	struct dvb_usb_device *d = i2c_get_adapdata(adap);
156902571aaa91263bc27e923e94ddf161c106befeeMauro Carvalho Chehab	int ret = 0, inc, i = 0;
157a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
158a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
159a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return -EAGAIN;
160a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
161a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	while (i < num) {
162a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
163a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			u8 buf[6];
164a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			buf[0] = CMD_I2C_READ;
165a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			buf[1] = msg[i].addr + 1;
166a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			buf[2] = msg[i].buf[0];
167a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			buf[3] = 0x00;
168a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			buf[4] = 0x00;
169a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			buf[5] = 0x01;
170a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf,
171a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari				msg[i+1].len);
172a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			inc = 2;
173a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		} else {
174a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			u8 buf[4+msg[i].len];
175a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			buf[0] = CMD_I2C_WRITE;
176a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			buf[1] = msg[i].addr;
177a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			buf[2] = msg[i].len;
178a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			buf[3] = 0x01;
179a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			memcpy(&buf[4], msg[i].buf, msg[i].len);
180a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
181a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			inc = 1;
182a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		}
183a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		if (ret)
184e613f8fa5432d4cacaf81615f62b6d25d77947c5Antti Palosaari			break;
185a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
186a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		i += inc;
187a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	}
188a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
189a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	mutex_unlock(&d->i2c_mutex);
190a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
191e613f8fa5432d4cacaf81615f62b6d25d77947c5Antti Palosaari	return ret ? ret : i;
192a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
193a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
194a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic u32 anysee_i2c_func(struct i2c_adapter *adapter)
195a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
196a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return I2C_FUNC_I2C;
197a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
198a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
199a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic struct i2c_algorithm anysee_i2c_algo = {
200a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.master_xfer   = anysee_master_xfer,
201a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.functionality = anysee_i2c_func,
202a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari};
203a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
204a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_mt352_demod_init(struct dvb_frontend *fe)
205a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
206ae3745f63ad28233d23f3a2f7407b95717d0dba8Antti Palosaari	static u8 clock_config[]   = { CLOCK_CTL,  0x38, 0x28 };
207ae3745f63ad28233d23f3a2f7407b95717d0dba8Antti Palosaari	static u8 reset[]          = { RESET,      0x80 };
208ae3745f63ad28233d23f3a2f7407b95717d0dba8Antti Palosaari	static u8 adc_ctl_1_cfg[]  = { ADC_CTL_1,  0x40 };
209ae3745f63ad28233d23f3a2f7407b95717d0dba8Antti Palosaari	static u8 agc_cfg[]        = { AGC_TARGET, 0x28, 0x20 };
210ae3745f63ad28233d23f3a2f7407b95717d0dba8Antti Palosaari	static u8 gpp_ctl_cfg[]    = { GPP_CTL,    0x33 };
211a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
212a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
213a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	mt352_write(fe, clock_config,   sizeof(clock_config));
214a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	udelay(200);
215a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	mt352_write(fe, reset,          sizeof(reset));
216a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	mt352_write(fe, adc_ctl_1_cfg,  sizeof(adc_ctl_1_cfg));
217a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
218a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	mt352_write(fe, agc_cfg,        sizeof(agc_cfg));
219a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	mt352_write(fe, gpp_ctl_cfg,    sizeof(gpp_ctl_cfg));
220a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
221a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
222a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return 0;
223a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
224a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
225a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari/* Callbacks for DVB USB */
226a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic struct tda10023_config anysee_tda10023_config = {
227a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.demod_address = 0x1a,
228a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.invert = 0,
229a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.xtal   = 16000000,
230a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.pll_m  = 11,
231a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.pll_p  = 3,
232a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.pll_n  = 1,
2335ae2fcaee4b0d6bf0fa5d9bd71e1291c9a9a6e60Antti Palosaari	.output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
2345ae2fcaee4b0d6bf0fa5d9bd71e1291c9a9a6e60Antti Palosaari	.deltaf = 0xfeeb,
235a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari};
236a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
237a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic struct mt352_config anysee_mt352_config = {
238a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.demod_address = 0x1e,
239a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.demod_init    = anysee_mt352_demod_init,
240a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari};
241a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
242a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic struct zl10353_config anysee_zl10353_config = {
243a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.demod_address = 0x1e,
244a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.parallel_ts = 1,
245a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari};
246a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
247a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_frontend_attach(struct dvb_usb_adapter *adap)
248a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
249a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	int ret;
250a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	struct anysee_state *state = adap->dev->priv;
251a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 hw_info[3];
252a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 io_d; /* IO port D */
253a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
254a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* check which hardware we have
255a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	   We must do this call two times to get reliable values (hw bug). */
256a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = anysee_get_hw_info(adap->dev, hw_info);
257a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
258a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return ret;
259a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = anysee_get_hw_info(adap->dev, hw_info);
260a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
261a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return ret;
262a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
263a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* Meaning of these info bytes are guessed. */
264a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	info("firmware version:%d.%d.%d hardware id:%d",
265a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		0, hw_info[1], hw_info[2], hw_info[0]);
266a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
267a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = anysee_read_reg(adap->dev, 0xb0, &io_d); /* IO port D */
268a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
269a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return ret;
270a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	deb_info("%s: IO port D:%02x\n", __func__, io_d);
271a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
272a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* Select demod using trial and error method. */
273a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
274a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* Try to attach demodulator in following order:
275a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	      model      demod     hw  firmware
276a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	   1. E30        MT352     02  0.2.1
277a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	   2. E30        ZL10353   02  0.2.1
2780f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari	   3. E30 Combo  ZL10353   0f  0.1.2    DVB-T/C combo
2790f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari	   4. E30 Plus   ZL10353   06  0.1.0
2800f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari	   5. E30C Plus  TDA10023  0a  0.1.0    rev 0.2
2810f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari	      E30C Plus  TDA10023  0f  0.1.2    rev 0.4
2820f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari	      E30 Combo  TDA10023  0f  0.1.2    DVB-T/C combo
283a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	*/
284a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
285a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */
286a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
287a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			      &adap->dev->i2c_adap);
288a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (adap->fe != NULL) {
289a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		state->tuner = DVB_PLL_THOMSON_DTT7579;
290a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return 0;
291a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	}
292a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
293a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */
294a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
295a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			      &adap->dev->i2c_adap);
296a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (adap->fe != NULL) {
297a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		state->tuner = DVB_PLL_THOMSON_DTT7579;
298a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return 0;
299a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	}
300a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
3010f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari	/* for E30 Combo Plus DVB-T demodulator */
3020f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari	if (dvb_usb_anysee_delsys) {
3030f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari		ret = anysee_write_reg(adap->dev, 0xb0, 0x01);
3040f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari		if (ret)
3050f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari			return ret;
3060f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari
3070f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari		/* Zarlink ZL10353 DVB-T demod */
3080f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari		adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
3090f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari				      &adap->dev->i2c_adap);
3100f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari		if (adap->fe != NULL) {
3110f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari			state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
3120f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari			return 0;
3130f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari		}
3140f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari	}
3150f77c3a4880f33127bc8d593e0e466f004a4addeAntti Palosaari
316a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* connect demod on IO port D for TDA10023 & ZL10353 */
317a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = anysee_write_reg(adap->dev, 0xb0, 0x25);
318a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
319a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return ret;
320a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
321a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */
322a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
323a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			      &adap->dev->i2c_adap);
324a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (adap->fe != NULL) {
325a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		state->tuner = DVB_PLL_THOMSON_DTT7579;
326a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return 0;
327a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	}
328a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
3295ae2fcaee4b0d6bf0fa5d9bd71e1291c9a9a6e60Antti Palosaari	/* IO port E - E30C rev 0.4 board requires this */
3305ae2fcaee4b0d6bf0fa5d9bd71e1291c9a9a6e60Antti Palosaari	ret = anysee_write_reg(adap->dev, 0xb1, 0xa7);
3315ae2fcaee4b0d6bf0fa5d9bd71e1291c9a9a6e60Antti Palosaari	if (ret)
3325ae2fcaee4b0d6bf0fa5d9bd71e1291c9a9a6e60Antti Palosaari		return ret;
333a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
334a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* Philips TDA10023 DVB-C demod */
335a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
336a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			      &adap->dev->i2c_adap, 0x48);
337a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (adap->fe != NULL) {
338a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
339a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return 0;
340a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	}
341a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
342a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* return IO port D to init value for safe */
343a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = anysee_write_reg(adap->dev, 0xb0, io_d);
344a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
345a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return ret;
346a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
347af901ca181d92aac3a7dc265144a9081a86d8f39André Goddard Rosa	err("Unknown Anysee version: %02x %02x %02x. "\
348a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	    "Please report the <linux-dvb@linuxtv.org>.",
349a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	    hw_info[0], hw_info[1], hw_info[2]);
350a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
351a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return -ENODEV;
352a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
353a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
354a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_tuner_attach(struct dvb_usb_adapter *adap)
355a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
356a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	struct anysee_state *state = adap->dev->priv;
357a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	deb_info("%s:\n", __func__);
358a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
359a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	switch (state->tuner) {
360a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	case DVB_PLL_THOMSON_DTT7579:
361a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		/* Thomson dtt7579 (not sure) PLL inside of:
362a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		   Samsung DNOS404ZH102A NIM
363a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		   Samsung DNOS404ZH103A NIM */
364a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		dvb_attach(dvb_pll_attach, adap->fe, 0x61,
365a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			   NULL, DVB_PLL_THOMSON_DTT7579);
366a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		break;
367a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	case DVB_PLL_SAMSUNG_DTOS403IH102A:
368a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		/* Unknown PLL inside of Samsung DTOS403IH102A tuner module */
369a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		dvb_attach(dvb_pll_attach, adap->fe, 0xc0,
370a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			   &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
371a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		break;
372a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	}
373a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
374a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return 0;
375a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
376a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
377a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaaristatic int anysee_rc_query(struct dvb_usb_device *d)
378a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
379a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 buf[] = {CMD_GET_IR_CODE};
380a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	u8 ircode[2];
381a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	int ret;
382a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari
383a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	/* Remote controller is basic NEC using address byte 0x08.
384a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	   Anysee device RC query returns only two bytes, status and code,
385a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	   address byte is dropped. Also it does not return any value for
386a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	   NEC RCs having address byte other than 0x08. Due to that, we
387a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	   cannot use that device as standard NEC receiver.
388a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	   It could be possible make hack which reads whole code directly
389a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	   from device memory... */
390a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
391a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
392a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
393a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return ret;
394a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
395a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	if (ircode[0]) {
396a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari		deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
397ca86674b8a93ea11c4bb6f4dd0113b1adf1fa841Mauro Carvalho Chehab		rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
398a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	}
399a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari
400a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return 0;
401a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
402a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
403a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari/* DVB USB Driver stuff */
404a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic struct dvb_usb_device_properties anysee_properties;
405a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
406a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int anysee_probe(struct usb_interface *intf,
407a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			const struct usb_device_id *id)
408a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
409a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	struct dvb_usb_device *d;
410a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	struct usb_host_interface *alt;
411a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	int ret;
412a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
413a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* There is one interface with two alternate settings.
414a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	   Alternate setting 0 is for bulk transfer.
415a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	   Alternate setting 1 is for isochronous transfer.
416a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	   We use bulk transfer (alternate setting 0). */
417a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (intf->num_altsetting < 1)
418a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return -ENODEV;
419a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
4208b0d7048dc2f0d2e4344bc8aaf85b4f14196145fDan Carpenter	/*
4218b0d7048dc2f0d2e4344bc8aaf85b4f14196145fDan Carpenter	 * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
4228b0d7048dc2f0d2e4344bc8aaf85b4f14196145fDan Carpenter	 * firmware from eeprom).  If dvb_usb_device_init() succeeds that
4238b0d7048dc2f0d2e4344bc8aaf85b4f14196145fDan Carpenter	 * means d is a valid pointer.
4248b0d7048dc2f0d2e4344bc8aaf85b4f14196145fDan Carpenter	 */
425a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
426a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		adapter_nr);
427a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
428a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return ret;
429a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
430a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	alt = usb_altnum_to_altsetting(intf, 0);
431a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (alt == NULL) {
432a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		deb_info("%s: no alt found!\n", __func__);
433a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return -ENODEV;
434a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	}
435a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
436a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
437a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		alt->desc.bAlternateSetting);
438a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
439a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		return ret;
440a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
4418b0d7048dc2f0d2e4344bc8aaf85b4f14196145fDan Carpenter	return anysee_init(d);
442a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
443a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
444ae3745f63ad28233d23f3a2f7407b95717d0dba8Antti Palosaaristatic struct usb_device_id anysee_table[] = {
445a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	{ USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
446a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	{ USB_DEVICE(USB_VID_AMT,     USB_PID_ANYSEE) },
447a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	{ }		/* Terminating entry */
448a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari};
449a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti PalosaariMODULE_DEVICE_TABLE(usb, anysee_table);
450a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
451a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic struct dvb_usb_device_properties anysee_properties = {
452a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.caps             = DVB_USB_IS_AN_I2C_ADAPTER,
453a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
454a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.usb_ctrl         = DEVICE_SPECIFIC,
455a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
456a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.size_of_priv     = sizeof(struct anysee_state),
457a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
458a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.num_adapters = 1,
459a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.adapter = {
460a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		{
461a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			.streaming_ctrl   = anysee_streaming_ctrl,
462a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			.frontend_attach  = anysee_frontend_attach,
463a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			.tuner_attach     = anysee_tuner_attach,
464a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			.stream = {
465a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari				.type = USB_BULK,
466a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari				.count = 8,
467a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari				.endpoint = 0x82,
468a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari				.u = {
469a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari					.bulk = {
470ab69333690c9e0f278d5ca1dab4e76015f7ecc66Antti Palosaari						.buffersize = (16*512),
471a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari					}
472a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari				}
473a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			},
474a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		}
475a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	},
476a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
477a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari	.rc.core = {
478a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari		.rc_codes         = RC_MAP_ANYSEE,
47952b661449aecc47e652a164c0d8078b31e10aca0Mauro Carvalho Chehab		.protocol         = RC_TYPE_OTHER,
480a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari		.module_name      = "anysee",
481f72a27b8ed4458bb9f7203408441d27382bc93f4Mauro Carvalho Chehab		.rc_query         = anysee_rc_query,
482a84946895fa747a81c3b55a1398e03cdba4778d9Antti Palosaari		.rc_interval      = 250,  /* windows driver uses 500ms */
483f72a27b8ed4458bb9f7203408441d27382bc93f4Mauro Carvalho Chehab	},
484a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
485a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.i2c_algo         = &anysee_i2c_algo,
486a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
487a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.generic_bulk_ctrl_endpoint = 1,
488a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
489a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.num_device_descs = 1,
490a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.devices = {
491a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		{
492a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			.name = "Anysee DVB USB2.0",
493a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			.cold_ids = {NULL},
494a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari			.warm_ids = {&anysee_table[0],
495a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari				     &anysee_table[1], NULL},
496a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		},
497a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	}
498a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari};
499a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
500a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic struct usb_driver anysee_driver = {
501a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.name       = "dvb_usb_anysee",
502a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.probe      = anysee_probe,
503a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.disconnect = dvb_usb_device_exit,
504a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	.id_table   = anysee_table,
505a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari};
506a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
507a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari/* module stuff */
508a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic int __init anysee_module_init(void)
509a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
510a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	int ret;
511a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
512a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	ret = usb_register(&anysee_driver);
513a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	if (ret)
514a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari		err("%s: usb_register failed. Error number %d", __func__, ret);
515a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
516a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	return ret;
517a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
518a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
519a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaaristatic void __exit anysee_module_exit(void)
520a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari{
521a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	/* deregister this driver from the USB subsystem */
522a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari	usb_deregister(&anysee_driver);
523a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari}
524a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
525a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaarimodule_init(anysee_module_init);
526a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaarimodule_exit(anysee_module_exit);
527a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti Palosaari
528a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti PalosaariMODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
529a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti PalosaariMODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
530a51e34dd6080d8d5c9e95a4e0292cd4cb889a61bAntti PalosaariMODULE_LICENSE("GPL");
531