141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham/*
241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	Mantis VP-2033 driver
341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
48825a0970cef408fb2f1a44e3cb05d6ba41a18dbManu Abraham	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	This program is free software; you can redistribute it and/or modify
741e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	it under the terms of the GNU General Public License as published by
841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	the Free Software Foundation; either version 2 of the License, or
941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	(at your option) any later version.
1041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
1141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	This program is distributed in the hope that it will be useful,
1241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	but WITHOUT ANY WARRANTY; without even the implied warranty of
1341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	GNU General Public License for more details.
1541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
1641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	You should have received a copy of the GNU General Public License
1741e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	along with this program; if not, write to the Free Software
1841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham*/
2041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
21b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include <linux/signal.h>
22b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include <linux/sched.h>
23b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include <linux/interrupt.h>
24b3b961448f702339444036f94252ff2ba7a99febManu Abraham
25b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "dmxdev.h"
26b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "dvbdev.h"
27b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "dvb_demux.h"
28b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "dvb_frontend.h"
29b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "dvb_net.h"
30b3b961448f702339444036f94252ff2ba7a99febManu Abraham
31b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "tda1002x.h"
3241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham#include "mantis_common.h"
33bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham#include "mantis_ioc.h"
34bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham#include "mantis_dvb.h"
3541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham#include "mantis_vp2033.h"
3641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
37df0cca174b4d85ea041509a13e5e68b377758bf1Manu Abraham#define MANTIS_MODEL_NAME	"VP-2033"
38df0cca174b4d85ea041509a13e5e68b377758bf1Manu Abraham#define MANTIS_DEV_TYPE		"DVB-C"
39df0cca174b4d85ea041509a13e5e68b377758bf1Manu Abraham
40b3b961448f702339444036f94252ff2ba7a99febManu Abrahamstruct tda1002x_config vp2033_tda1002x_cu1216_config = {
41b3b961448f702339444036f94252ff2ba7a99febManu Abraham	.demod_address = 0x18 >> 1,
42b3b961448f702339444036f94252ff2ba7a99febManu Abraham	.invert = 1,
43df0cca174b4d85ea041509a13e5e68b377758bf1Manu Abraham};
44df0cca174b4d85ea041509a13e5e68b377758bf1Manu Abraham
45b3b961448f702339444036f94252ff2ba7a99febManu Abrahamstruct tda10023_config vp2033_tda10023_cu1216_config = {
462687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	.demod_address = 0x18 >> 1,
472687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	.invert = 1,
4841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham};
4941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
50b3b961448f702339444036f94252ff2ba7a99febManu Abrahamstatic u8 read_pwm(struct mantis_pci *mantis)
5141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham{
52b3b961448f702339444036f94252ff2ba7a99febManu Abraham	struct i2c_adapter *adapter = &mantis->adapter;
53b3b961448f702339444036f94252ff2ba7a99febManu Abraham
542687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	u8 b = 0xff;
552687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	u8 pwm;
562687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	struct i2c_msg msg[] = {
57b3b961448f702339444036f94252ff2ba7a99febManu Abraham		{.addr = 0x50, .flags = 0, .buf = &b, .len = 1},
58b3b961448f702339444036f94252ff2ba7a99febManu Abraham		{.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1}
592687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	};
6041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
61b3b961448f702339444036f94252ff2ba7a99febManu Abraham	if ((i2c_transfer(adapter, msg, 2) != 2)
622687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	    || (pwm == 0xff))
632687d832fe0141015e2391f3755d9499e6efb83eManu Abraham		pwm = 0x48;
6441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
652687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	return pwm;
662687d832fe0141015e2391f3755d9499e6efb83eManu Abraham}
672687d832fe0141015e2391f3755d9499e6efb83eManu Abraham
6814d24d148c7521b2b88b396652e36f55d061e195Mauro Carvalho Chehabstatic int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe)
692687d832fe0141015e2391f3755d9499e6efb83eManu Abraham{
70f0b6c2a90f5c075ea9f5b069418bb995acb1b363Mauro Carvalho Chehab	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
712687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	struct mantis_pci *mantis = fe->dvb->priv;
72b3b961448f702339444036f94252ff2ba7a99febManu Abraham	struct i2c_adapter *adapter = &mantis->adapter;
732687d832fe0141015e2391f3755d9499e6efb83eManu Abraham
742687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	u8 buf[6];
75f5ae4f6f482191c531ea9e50ac91d9bd2ffca171Manu Abraham	struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)};
762687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	int i;
7741e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
782687d832fe0141015e2391f3755d9499e6efb83eManu Abraham#define CU1216_IF 36125000
7941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham#define TUNER_MUL 62500
8041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
81f0b6c2a90f5c075ea9f5b069418bb995acb1b363Mauro Carvalho Chehab	u32 div = (p->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
8241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
8341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	buf[0] = (div >> 8) & 0x7f;
8441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	buf[1] = div & 0xff;
852687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	buf[2] = 0xce;
86f0b6c2a90f5c075ea9f5b069418bb995acb1b363Mauro Carvalho Chehab	buf[3] = (p->frequency < 150000000 ? 0x01 :
87f0b6c2a90f5c075ea9f5b069418bb995acb1b363Mauro Carvalho Chehab		  p->frequency < 445000000 ? 0x02 : 0x04);
882687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	buf[4] = 0xde;
892687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	buf[5] = 0x20;
9041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
912687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	if (fe->ops.i2c_gate_ctrl)
922687d832fe0141015e2391f3755d9499e6efb83eManu Abraham		fe->ops.i2c_gate_ctrl(fe, 1);
932687d832fe0141015e2391f3755d9499e6efb83eManu Abraham
94b3b961448f702339444036f94252ff2ba7a99febManu Abraham	if (i2c_transfer(adapter, &msg, 1) != 1)
9541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		return -EIO;
962687d832fe0141015e2391f3755d9499e6efb83eManu Abraham
972687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	/* wait for the pll lock */
982687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	msg.flags = I2C_M_RD;
992687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	msg.len = 1;
1002687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	for (i = 0; i < 20; i++) {
1012687d832fe0141015e2391f3755d9499e6efb83eManu Abraham		if (fe->ops.i2c_gate_ctrl)
1022687d832fe0141015e2391f3755d9499e6efb83eManu Abraham			fe->ops.i2c_gate_ctrl(fe, 1);
1032687d832fe0141015e2391f3755d9499e6efb83eManu Abraham
104b3b961448f702339444036f94252ff2ba7a99febManu Abraham		if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40))
1052687d832fe0141015e2391f3755d9499e6efb83eManu Abraham			break;
1062687d832fe0141015e2391f3755d9499e6efb83eManu Abraham
1072687d832fe0141015e2391f3755d9499e6efb83eManu Abraham		msleep(10);
10841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	}
1092687d832fe0141015e2391f3755d9499e6efb83eManu Abraham
1102687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	/* switch the charge pump to the lower current */
1112687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	msg.flags = 0;
1122687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	msg.len = 2;
1132687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	msg.buf = &buf[2];
1142687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	buf[2] &= ~0x40;
1152687d832fe0141015e2391f3755d9499e6efb83eManu Abraham	if (fe->ops.i2c_gate_ctrl)
1162687d832fe0141015e2391f3755d9499e6efb83eManu Abraham		fe->ops.i2c_gate_ctrl(fe, 1);
1172687d832fe0141015e2391f3755d9499e6efb83eManu Abraham
118b3b961448f702339444036f94252ff2ba7a99febManu Abraham	if (i2c_transfer(adapter, &msg, 1) != 1)
1192687d832fe0141015e2391f3755d9499e6efb83eManu Abraham		return -EIO;
120da7365f46607207c8166167ba497e3cb3e02270dManu Abraham
12141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	return 0;
12241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham}
123b3b961448f702339444036f94252ff2ba7a99febManu Abraham
124b3b961448f702339444036f94252ff2ba7a99febManu Abrahamstatic int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
125b3b961448f702339444036f94252ff2ba7a99febManu Abraham{
126b3b961448f702339444036f94252ff2ba7a99febManu Abraham	struct i2c_adapter *adapter = &mantis->adapter;
127b3b961448f702339444036f94252ff2ba7a99febManu Abraham
128bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham	int err = 0;
129b3b961448f702339444036f94252ff2ba7a99febManu Abraham
130bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham	err = mantis_frontend_power(mantis, POWER_ON);
131bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham	if (err == 0) {
132bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		mantis_frontend_soft_reset(mantis);
133bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		msleep(250);
134bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham
135bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
136a22407faba57c3624beea1a9fad7cbdcf5a19a1aBjørn Mork		fe = dvb_attach(tda10021_attach, &vp2033_tda1002x_cu1216_config,
137b3b961448f702339444036f94252ff2ba7a99febManu Abraham				     adapter,
138b3b961448f702339444036f94252ff2ba7a99febManu Abraham				     read_pwm(mantis));
139b3b961448f702339444036f94252ff2ba7a99febManu Abraham
140b3b961448f702339444036f94252ff2ba7a99febManu Abraham		if (fe) {
141b3b961448f702339444036f94252ff2ba7a99febManu Abraham			dprintk(MANTIS_ERROR, 1,
142bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham				"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
143b3b961448f702339444036f94252ff2ba7a99febManu Abraham				vp2033_tda1002x_cu1216_config.demod_address);
144bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		} else {
145a22407faba57c3624beea1a9fad7cbdcf5a19a1aBjørn Mork			fe = dvb_attach(tda10023_attach, &vp2033_tda10023_cu1216_config,
146bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham					     adapter,
147bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham					     read_pwm(mantis));
148bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham
149bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			if (fe) {
150bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham				dprintk(MANTIS_ERROR, 1,
151bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham					"found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x",
152bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham					vp2033_tda1002x_cu1216_config.demod_address);
153bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			}
154b3b961448f702339444036f94252ff2ba7a99febManu Abraham		}
155b3b961448f702339444036f94252ff2ba7a99febManu Abraham
156bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		if (fe) {
157bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set;
158bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success");
159bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		} else {
160bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			return -1;
161bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		}
162b3b961448f702339444036f94252ff2ba7a99febManu Abraham	} else {
163bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
164bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			adapter->name,
165bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			err);
166bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham
167bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		return -EIO;
168b3b961448f702339444036f94252ff2ba7a99febManu Abraham	}
169b3b961448f702339444036f94252ff2ba7a99febManu Abraham
170b3b961448f702339444036f94252ff2ba7a99febManu Abraham	mantis->fe = fe;
171b3b961448f702339444036f94252ff2ba7a99febManu Abraham	dprintk(MANTIS_DEBUG, 1, "Done!");
172b3b961448f702339444036f94252ff2ba7a99febManu Abraham
173b3b961448f702339444036f94252ff2ba7a99febManu Abraham	return 0;
174b3b961448f702339444036f94252ff2ba7a99febManu Abraham}
175b3b961448f702339444036f94252ff2ba7a99febManu Abraham
176b3b961448f702339444036f94252ff2ba7a99febManu Abrahamstruct mantis_hwconfig vp2033_config = {
177b3b961448f702339444036f94252ff2ba7a99febManu Abraham	.model_name	= MANTIS_MODEL_NAME,
178b3b961448f702339444036f94252ff2ba7a99febManu Abraham	.dev_type	= MANTIS_DEV_TYPE,
179b3b961448f702339444036f94252ff2ba7a99febManu Abraham	.ts_size	= MANTIS_TS_204,
180b3b961448f702339444036f94252ff2ba7a99febManu Abraham
181b3b961448f702339444036f94252ff2ba7a99febManu Abraham	.baud_rate	= MANTIS_BAUD_9600,
182b3b961448f702339444036f94252ff2ba7a99febManu Abraham	.parity		= MANTIS_PARITY_NONE,
183b3b961448f702339444036f94252ff2ba7a99febManu Abraham	.bytes		= 0,
184b3b961448f702339444036f94252ff2ba7a99febManu Abraham
185b3b961448f702339444036f94252ff2ba7a99febManu Abraham	.frontend_init	= vp2033_frontend_init,
186bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham	.power		= GPIF_A12,
187bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham	.reset		= GPIF_A13,
188b3b961448f702339444036f94252ff2ba7a99febManu Abraham};
189