1/*
2 *  Driver for Zarlink ZL10039 DVB-S tuner
3 *
4 *  Copyright 2007 Jan D. Louw <jd.louw@mweb.co.za>
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#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/string.h>
25#include <linux/slab.h>
26#include <linux/dvb/frontend.h>
27
28#include "dvb_frontend.h"
29#include "zl10039.h"
30
31static int debug;
32
33/* Max transfer size done by I2C transfer functions */
34#define MAX_XFER_SIZE  64
35
36#define dprintk(args...) \
37	do { \
38		if (debug) \
39			printk(KERN_DEBUG args); \
40	} while (0)
41
42enum zl10039_model_id {
43	ID_ZL10039 = 1
44};
45
46struct zl10039_state {
47	struct i2c_adapter *i2c;
48	u8 i2c_addr;
49	u8 id;
50};
51
52enum zl10039_reg_addr {
53	PLL0 = 0,
54	PLL1,
55	PLL2,
56	PLL3,
57	RFFE,
58	BASE0,
59	BASE1,
60	BASE2,
61	LO0,
62	LO1,
63	LO2,
64	LO3,
65	LO4,
66	LO5,
67	LO6,
68	GENERAL
69};
70
71static int zl10039_read(const struct zl10039_state *state,
72			const enum zl10039_reg_addr reg, u8 *buf,
73			const size_t count)
74{
75	u8 regbuf[] = { reg };
76	struct i2c_msg msg[] = {
77		{/* Write register address */
78			.addr = state->i2c_addr,
79			.flags = 0,
80			.buf = regbuf,
81			.len = 1,
82		}, {/* Read count bytes */
83			.addr = state->i2c_addr,
84			.flags = I2C_M_RD,
85			.buf = buf,
86			.len = count,
87		},
88	};
89
90	dprintk("%s\n", __func__);
91
92	if (i2c_transfer(state->i2c, msg, 2) != 2) {
93		dprintk("%s: i2c read error\n", __func__);
94		return -EREMOTEIO;
95	}
96
97	return 0; /* Success */
98}
99
100static int zl10039_write(struct zl10039_state *state,
101			const enum zl10039_reg_addr reg, const u8 *src,
102			const size_t count)
103{
104	u8 buf[MAX_XFER_SIZE];
105	struct i2c_msg msg = {
106		.addr = state->i2c_addr,
107		.flags = 0,
108		.buf = buf,
109		.len = count + 1,
110	};
111
112	if (1 + count > sizeof(buf)) {
113		printk(KERN_WARNING
114		       "%s: i2c wr reg=%04x: len=%zu is too big!\n",
115		       KBUILD_MODNAME, reg, count);
116		return -EINVAL;
117	}
118
119	dprintk("%s\n", __func__);
120	/* Write register address and data in one go */
121	buf[0] = reg;
122	memcpy(&buf[1], src, count);
123	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
124		dprintk("%s: i2c write error\n", __func__);
125		return -EREMOTEIO;
126	}
127
128	return 0; /* Success */
129}
130
131static inline int zl10039_readreg(struct zl10039_state *state,
132				const enum zl10039_reg_addr reg, u8 *val)
133{
134	return zl10039_read(state, reg, val, 1);
135}
136
137static inline int zl10039_writereg(struct zl10039_state *state,
138				const enum zl10039_reg_addr reg,
139				const u8 val)
140{
141	return zl10039_write(state, reg, &val, 1);
142}
143
144static int zl10039_init(struct dvb_frontend *fe)
145{
146	struct zl10039_state *state = fe->tuner_priv;
147	int ret;
148
149	dprintk("%s\n", __func__);
150	if (fe->ops.i2c_gate_ctrl)
151		fe->ops.i2c_gate_ctrl(fe, 1);
152	/* Reset logic */
153	ret = zl10039_writereg(state, GENERAL, 0x40);
154	if (ret < 0) {
155		dprintk("Note: i2c write error normal when resetting the "
156			"tuner\n");
157	}
158	/* Wake up */
159	ret = zl10039_writereg(state, GENERAL, 0x01);
160	if (ret < 0) {
161		dprintk("Tuner power up failed\n");
162		return ret;
163	}
164	if (fe->ops.i2c_gate_ctrl)
165		fe->ops.i2c_gate_ctrl(fe, 0);
166
167	return 0;
168}
169
170static int zl10039_sleep(struct dvb_frontend *fe)
171{
172	struct zl10039_state *state = fe->tuner_priv;
173	int ret;
174
175	dprintk("%s\n", __func__);
176	if (fe->ops.i2c_gate_ctrl)
177		fe->ops.i2c_gate_ctrl(fe, 1);
178	ret = zl10039_writereg(state, GENERAL, 0x80);
179	if (ret < 0) {
180		dprintk("Tuner sleep failed\n");
181		return ret;
182	}
183	if (fe->ops.i2c_gate_ctrl)
184		fe->ops.i2c_gate_ctrl(fe, 0);
185
186	return 0;
187}
188
189static int zl10039_set_params(struct dvb_frontend *fe)
190{
191	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
192	struct zl10039_state *state = fe->tuner_priv;
193	u8 buf[6];
194	u8 bf;
195	u32 fbw;
196	u32 div;
197	int ret;
198
199	dprintk("%s\n", __func__);
200	dprintk("Set frequency = %d, symbol rate = %d\n",
201			c->frequency, c->symbol_rate);
202
203	/* Assumed 10.111 MHz crystal oscillator */
204	/* Cancelled num/den 80 to prevent overflow */
205	div = (c->frequency * 1000) / 126387;
206	fbw = (c->symbol_rate * 27) / 32000;
207	/* Cancelled num/den 10 to prevent overflow */
208	bf = ((fbw * 5088) / 1011100) - 1;
209
210	/*PLL divider*/
211	buf[0] = (div >> 8) & 0x7f;
212	buf[1] = (div >> 0) & 0xff;
213	/*Reference divider*/
214	/* Select reference ratio of 80 */
215	buf[2] = 0x1D;
216	/*PLL test modes*/
217	buf[3] = 0x40;
218	/*RF Control register*/
219	buf[4] = 0x6E; /* Bypass enable */
220	/*Baseband filter cutoff */
221	buf[5] = bf;
222
223	/* Open i2c gate */
224	if (fe->ops.i2c_gate_ctrl)
225		fe->ops.i2c_gate_ctrl(fe, 1);
226	/* BR = 10, Enable filter adjustment */
227	ret = zl10039_writereg(state, BASE1, 0x0A);
228	if (ret < 0)
229		goto error;
230	/* Write new config values */
231	ret = zl10039_write(state, PLL0, buf, sizeof(buf));
232	if (ret < 0)
233		goto error;
234	/* BR = 10, Disable filter adjustment */
235	ret = zl10039_writereg(state, BASE1, 0x6A);
236	if (ret < 0)
237		goto error;
238
239	/* Close i2c gate */
240	if (fe->ops.i2c_gate_ctrl)
241		fe->ops.i2c_gate_ctrl(fe, 0);
242	return 0;
243error:
244	dprintk("Error setting tuner\n");
245	return ret;
246}
247
248static int zl10039_release(struct dvb_frontend *fe)
249{
250	struct zl10039_state *state = fe->tuner_priv;
251
252	dprintk("%s\n", __func__);
253	kfree(state);
254	fe->tuner_priv = NULL;
255	return 0;
256}
257
258static struct dvb_tuner_ops zl10039_ops = {
259	.release = zl10039_release,
260	.init = zl10039_init,
261	.sleep = zl10039_sleep,
262	.set_params = zl10039_set_params,
263};
264
265struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
266		u8 i2c_addr, struct i2c_adapter *i2c)
267{
268	struct zl10039_state *state = NULL;
269
270	dprintk("%s\n", __func__);
271	state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL);
272	if (state == NULL)
273		goto error;
274
275	state->i2c = i2c;
276	state->i2c_addr = i2c_addr;
277
278	/* Open i2c gate */
279	if (fe->ops.i2c_gate_ctrl)
280		fe->ops.i2c_gate_ctrl(fe, 1);
281	/* check if this is a valid tuner */
282	if (zl10039_readreg(state, GENERAL, &state->id) < 0) {
283		/* Close i2c gate */
284		if (fe->ops.i2c_gate_ctrl)
285			fe->ops.i2c_gate_ctrl(fe, 0);
286		goto error;
287	}
288	/* Close i2c gate */
289	if (fe->ops.i2c_gate_ctrl)
290		fe->ops.i2c_gate_ctrl(fe, 0);
291
292	state->id = state->id & 0x0f;
293	switch (state->id) {
294	case ID_ZL10039:
295		strcpy(fe->ops.tuner_ops.info.name,
296			"Zarlink ZL10039 DVB-S tuner");
297		break;
298	default:
299		dprintk("Chip ID=%x does not match a known type\n", state->id);
300		goto error;
301	}
302
303	memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops));
304	fe->tuner_priv = state;
305	dprintk("Tuner attached @ i2c address 0x%02x\n", i2c_addr);
306	return fe;
307error:
308	kfree(state);
309	return NULL;
310}
311EXPORT_SYMBOL(zl10039_attach);
312
313module_param(debug, int, 0644);
314MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
315MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver");
316MODULE_AUTHOR("Jan D. Louw <jd.louw@mweb.co.za>");
317MODULE_LICENSE("GPL");
318