1 /*
2 	Mantis VP-1033 driver
3 
4 	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
5 
6 	This program is free software; you can redistribute it and/or modify
7 	it under the terms of the GNU General Public License as published by
8 	the Free Software Foundation; either version 2 of the License, or
9 	(at your option) any later version.
10 
11 	This program is distributed in the hope that it will be useful,
12 	but WITHOUT ANY WARRANTY; without even the implied warranty of
13 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 	GNU General Public License for more details.
15 
16 	You should have received a copy of the GNU General Public License
17 	along with this program; if not, write to the Free Software
18 	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 
21 #include <linux/signal.h>
22 #include <linux/sched.h>
23 #include <linux/interrupt.h>
24 
25 #include <media/dmxdev.h>
26 #include <media/dvbdev.h>
27 #include <media/dvb_demux.h>
28 #include <media/dvb_frontend.h>
29 #include <media/dvb_net.h>
30 
31 #include "stv0299.h"
32 #include "mantis_common.h"
33 #include "mantis_ioc.h"
34 #include "mantis_dvb.h"
35 #include "mantis_vp1033.h"
36 #include "mantis_reg.h"
37 
38 static u8 lgtdqcs001f_inittab[] = {
39 	0x01, 0x15,
40 	0x02, 0x30,
41 	0x03, 0x00,
42 	0x04, 0x2a,
43 	0x05, 0x85,
44 	0x06, 0x02,
45 	0x07, 0x00,
46 	0x08, 0x00,
47 	0x0c, 0x01,
48 	0x0d, 0x81,
49 	0x0e, 0x44,
50 	0x0f, 0x94,
51 	0x10, 0x3c,
52 	0x11, 0x84,
53 	0x12, 0xb9,
54 	0x13, 0xb5,
55 	0x14, 0x4f,
56 	0x15, 0xc9,
57 	0x16, 0x80,
58 	0x17, 0x36,
59 	0x18, 0xfb,
60 	0x19, 0xcf,
61 	0x1a, 0xbc,
62 	0x1c, 0x2b,
63 	0x1d, 0x27,
64 	0x1e, 0x00,
65 	0x1f, 0x0b,
66 	0x20, 0xa1,
67 	0x21, 0x60,
68 	0x22, 0x00,
69 	0x23, 0x00,
70 	0x28, 0x00,
71 	0x29, 0x28,
72 	0x2a, 0x14,
73 	0x2b, 0x0f,
74 	0x2c, 0x09,
75 	0x2d, 0x05,
76 	0x31, 0x1f,
77 	0x32, 0x19,
78 	0x33, 0xfc,
79 	0x34, 0x13,
80 	0xff, 0xff,
81 };
82 
83 #define MANTIS_MODEL_NAME	"VP-1033"
84 #define MANTIS_DEV_TYPE		"DVB-S/DSS"
85 
86 static int lgtdqcs001f_tuner_set(struct dvb_frontend *fe)
87 {
88 	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
89 	struct mantis_pci *mantis	= fe->dvb->priv;
90 	struct i2c_adapter *adapter	= &mantis->adapter;
91 
92 	u8 buf[4];
93 	u32 div;
94 
95 
96 	struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)};
97 
98 	div = p->frequency / 250;
99 
100 	buf[0] = (div >> 8) & 0x7f;
101 	buf[1] =  div & 0xff;
102 	buf[2] =  0x83;
103 	buf[3] =  0xc0;
104 
105 	if (p->frequency < 1531000)
106 		buf[3] |= 0x04;
107 	else
108 		buf[3] &= ~0x04;
109 	if (i2c_transfer(adapter, &msg, 1) < 0) {
110 		dprintk(MANTIS_ERROR, 1, "Write: I2C Transfer failed");
111 		return -EIO;
112 	}
113 	msleep_interruptible(100);
114 
115 	return 0;
116 }
117 
118 static int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe,
119 				       u32 srate, u32 ratio)
120 {
121 	u8 aclk = 0;
122 	u8 bclk = 0;
123 
124 	if (srate < 1500000) {
125 		aclk = 0xb7;
126 		bclk = 0x47;
127 	} else if (srate < 3000000) {
128 		aclk = 0xb7;
129 		bclk = 0x4b;
130 	} else if (srate < 7000000) {
131 		aclk = 0xb7;
132 		bclk = 0x4f;
133 	} else if (srate < 14000000) {
134 		aclk = 0xb7;
135 		bclk = 0x53;
136 	} else if (srate < 30000000) {
137 		aclk = 0xb6;
138 		bclk = 0x53;
139 	} else if (srate < 45000000) {
140 		aclk = 0xb4;
141 		bclk = 0x51;
142 	}
143 	stv0299_writereg(fe, 0x13, aclk);
144 	stv0299_writereg(fe, 0x14, bclk);
145 
146 	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
147 	stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
148 	stv0299_writereg(fe, 0x21,  ratio & 0xf0);
149 
150 	return 0;
151 }
152 
153 static struct stv0299_config lgtdqcs001f_config = {
154 	.demod_address		= 0x68,
155 	.inittab		= lgtdqcs001f_inittab,
156 	.mclk			= 88000000UL,
157 	.invert			= 0,
158 	.skip_reinit		= 0,
159 	.volt13_op0_op1		= STV0299_VOLT13_OP0,
160 	.min_delay_ms		= 100,
161 	.set_symbol_rate	= lgtdqcs001f_set_symbol_rate,
162 };
163 
164 static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
165 {
166 	struct i2c_adapter *adapter	= &mantis->adapter;
167 
168 	int err = 0;
169 
170 	err = mantis_frontend_power(mantis, POWER_ON);
171 	if (err == 0) {
172 		mantis_frontend_soft_reset(mantis);
173 		msleep(250);
174 
175 		dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
176 		fe = dvb_attach(stv0299_attach, &lgtdqcs001f_config, adapter);
177 
178 		if (fe) {
179 			fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;
180 			dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x",
181 				lgtdqcs001f_config.demod_address);
182 
183 			dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success");
184 		} else {
185 			return -1;
186 		}
187 	} else {
188 		dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
189 			adapter->name,
190 			err);
191 
192 		return -EIO;
193 	}
194 	mantis->fe = fe;
195 	dprintk(MANTIS_ERROR, 1, "Done!");
196 
197 	return 0;
198 }
199 
200 struct mantis_hwconfig vp1033_config = {
201 	.model_name		= MANTIS_MODEL_NAME,
202 	.dev_type		= MANTIS_DEV_TYPE,
203 	.ts_size		= MANTIS_TS_204,
204 
205 	.baud_rate		= MANTIS_BAUD_9600,
206 	.parity			= MANTIS_PARITY_NONE,
207 	.bytes			= 0,
208 
209 	.frontend_init		= vp1033_frontend_init,
210 	.power			= GPIF_A12,
211 	.reset			= GPIF_A13,
212 };
213