1  /*
2     Driver for ST STB6000 DVBS Silicon tuner
3
4     Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
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
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21  */
22
23#include <linux/slab.h>
24#include <linux/module.h>
25#include <linux/dvb/frontend.h>
26#include <asm/types.h>
27
28#include "stb6000.h"
29
30static int debug;
31#define dprintk(args...) \
32	do { \
33		if (debug) \
34			printk(KERN_DEBUG "stb6000: " args); \
35	} while (0)
36
37struct stb6000_priv {
38	/* i2c details */
39	int i2c_address;
40	struct i2c_adapter *i2c;
41	u32 frequency;
42};
43
44static int stb6000_release(struct dvb_frontend *fe)
45{
46	kfree(fe->tuner_priv);
47	fe->tuner_priv = NULL;
48	return 0;
49}
50
51static int stb6000_sleep(struct dvb_frontend *fe)
52{
53	struct stb6000_priv *priv = fe->tuner_priv;
54	int ret;
55	u8 buf[] = { 10, 0 };
56	struct i2c_msg msg = {
57		.addr = priv->i2c_address,
58		.flags = 0,
59		.buf = buf,
60		.len = 2
61	};
62
63	dprintk("%s:\n", __func__);
64
65	if (fe->ops.i2c_gate_ctrl)
66		fe->ops.i2c_gate_ctrl(fe, 1);
67
68	ret = i2c_transfer(priv->i2c, &msg, 1);
69	if (ret != 1)
70		dprintk("%s: i2c error\n", __func__);
71
72	if (fe->ops.i2c_gate_ctrl)
73		fe->ops.i2c_gate_ctrl(fe, 0);
74
75	return (ret == 1) ? 0 : ret;
76}
77
78static int stb6000_set_params(struct dvb_frontend *fe)
79{
80	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
81	struct stb6000_priv *priv = fe->tuner_priv;
82	unsigned int n, m;
83	int ret;
84	u32 freq_mhz;
85	int bandwidth;
86	u8 buf[12];
87	struct i2c_msg msg = {
88		.addr = priv->i2c_address,
89		.flags = 0,
90		.buf = buf,
91		.len = 12
92	};
93
94	dprintk("%s:\n", __func__);
95
96	freq_mhz = p->frequency / 1000;
97	bandwidth = p->symbol_rate / 1000000;
98
99	if (bandwidth > 31)
100		bandwidth = 31;
101
102	if ((freq_mhz > 949) && (freq_mhz < 2151)) {
103		buf[0] = 0x01;
104		buf[1] = 0xac;
105		if (freq_mhz < 1950)
106			buf[1] = 0xaa;
107		if (freq_mhz < 1800)
108			buf[1] = 0xa8;
109		if (freq_mhz < 1650)
110			buf[1] = 0xa6;
111		if (freq_mhz < 1530)
112			buf[1] = 0xa5;
113		if (freq_mhz < 1470)
114			buf[1] = 0xa4;
115		if (freq_mhz < 1370)
116			buf[1] = 0xa2;
117		if (freq_mhz < 1300)
118			buf[1] = 0xa1;
119		if (freq_mhz < 1200)
120			buf[1] = 0xa0;
121		if (freq_mhz < 1075)
122			buf[1] = 0xbc;
123		if (freq_mhz < 1000)
124			buf[1] = 0xba;
125		if (freq_mhz < 1075) {
126			n = freq_mhz / 8; /* vco=lo*4 */
127			m = 2;
128		} else {
129			n = freq_mhz / 16; /* vco=lo*2 */
130			m = 1;
131		}
132		buf[2] = n >> 1;
133		buf[3] = (unsigned char)(((n & 1) << 7) |
134					(m * freq_mhz - n * 16) | 0x60);
135		buf[4] = 0x04;
136		buf[5] = 0x0e;
137
138		buf[6] = (unsigned char)(bandwidth);
139
140		buf[7] = 0xd8;
141		buf[8] = 0xd0;
142		buf[9] = 0x50;
143		buf[10] = 0xeb;
144		buf[11] = 0x4f;
145
146		if (fe->ops.i2c_gate_ctrl)
147			fe->ops.i2c_gate_ctrl(fe, 1);
148
149		ret = i2c_transfer(priv->i2c, &msg, 1);
150		if (ret != 1)
151			dprintk("%s: i2c error\n", __func__);
152
153		udelay(10);
154		if (fe->ops.i2c_gate_ctrl)
155			fe->ops.i2c_gate_ctrl(fe, 0);
156
157		buf[0] = 0x07;
158		buf[1] = 0xdf;
159		buf[2] = 0xd0;
160		buf[3] = 0x50;
161		buf[4] = 0xfb;
162		msg.len = 5;
163
164		if (fe->ops.i2c_gate_ctrl)
165			fe->ops.i2c_gate_ctrl(fe, 1);
166
167		ret = i2c_transfer(priv->i2c, &msg, 1);
168		if (ret != 1)
169			dprintk("%s: i2c error\n", __func__);
170
171		udelay(10);
172		if (fe->ops.i2c_gate_ctrl)
173			fe->ops.i2c_gate_ctrl(fe, 0);
174
175		priv->frequency = freq_mhz * 1000;
176
177		return (ret == 1) ? 0 : ret;
178	}
179	return -1;
180}
181
182static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
183{
184	struct stb6000_priv *priv = fe->tuner_priv;
185	*frequency = priv->frequency;
186	return 0;
187}
188
189static struct dvb_tuner_ops stb6000_tuner_ops = {
190	.info = {
191		.name = "ST STB6000",
192		.frequency_min = 950000,
193		.frequency_max = 2150000
194	},
195	.release = stb6000_release,
196	.sleep = stb6000_sleep,
197	.set_params = stb6000_set_params,
198	.get_frequency = stb6000_get_frequency,
199};
200
201struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
202						struct i2c_adapter *i2c)
203{
204	struct stb6000_priv *priv = NULL;
205	u8 b0[] = { 0 };
206	u8 b1[] = { 0, 0 };
207	struct i2c_msg msg[2] = {
208		{
209			.addr = addr,
210			.flags = 0,
211			.buf = b0,
212			.len = 0
213		}, {
214			.addr = addr,
215			.flags = I2C_M_RD,
216			.buf = b1,
217			.len = 2
218		}
219	};
220	int ret;
221
222	dprintk("%s:\n", __func__);
223
224	if (fe->ops.i2c_gate_ctrl)
225		fe->ops.i2c_gate_ctrl(fe, 1);
226
227	/* is some i2c device here ? */
228	ret = i2c_transfer(i2c, msg, 2);
229	if (fe->ops.i2c_gate_ctrl)
230		fe->ops.i2c_gate_ctrl(fe, 0);
231
232	if (ret != 2)
233		return NULL;
234
235	priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
236	if (priv == NULL)
237		return NULL;
238
239	priv->i2c_address = addr;
240	priv->i2c = i2c;
241
242	memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
243				sizeof(struct dvb_tuner_ops));
244
245	fe->tuner_priv = priv;
246
247	return fe;
248}
249EXPORT_SYMBOL(stb6000_attach);
250
251module_param(debug, int, 0644);
252MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
253
254MODULE_DESCRIPTION("DVB STB6000 driver");
255MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
256MODULE_LICENSE("GPL");
257