xref: /linux/drivers/media/dvb-frontends/ds3000.c (revision c1965eae65f0db2eee574f72aab4e8b34ecf8f9c)
109ea33e5SIgor M. Liplianin /*
2*c1965eaeSKonstantin Dimitrov     Montage Technology DS3000 - DVBS/S2 Demodulator driver
3*c1965eaeSKonstantin Dimitrov     Copyright (C) 2009-2012 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
409ea33e5SIgor M. Liplianin 
5*c1965eaeSKonstantin Dimitrov     Copyright (C) 2009-2012 TurboSight.com
609ea33e5SIgor M. Liplianin 
709ea33e5SIgor M. Liplianin     This program is free software; you can redistribute it and/or modify
809ea33e5SIgor M. Liplianin     it under the terms of the GNU General Public License as published by
909ea33e5SIgor M. Liplianin     the Free Software Foundation; either version 2 of the License, or
1009ea33e5SIgor M. Liplianin     (at your option) any later version.
1109ea33e5SIgor M. Liplianin 
1209ea33e5SIgor M. Liplianin     This program is distributed in the hope that it will be useful,
1309ea33e5SIgor M. Liplianin     but WITHOUT ANY WARRANTY; without even the implied warranty of
1409ea33e5SIgor M. Liplianin     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1509ea33e5SIgor M. Liplianin     GNU General Public License for more details.
1609ea33e5SIgor M. Liplianin 
1709ea33e5SIgor M. Liplianin     You should have received a copy of the GNU General Public License
1809ea33e5SIgor M. Liplianin     along with this program; if not, write to the Free Software
1909ea33e5SIgor M. Liplianin     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2009ea33e5SIgor M. Liplianin  */
2109ea33e5SIgor M. Liplianin 
2209ea33e5SIgor M. Liplianin #include <linux/slab.h>
2309ea33e5SIgor M. Liplianin #include <linux/kernel.h>
2409ea33e5SIgor M. Liplianin #include <linux/module.h>
2509ea33e5SIgor M. Liplianin #include <linux/moduleparam.h>
2609ea33e5SIgor M. Liplianin #include <linux/init.h>
2709ea33e5SIgor M. Liplianin #include <linux/firmware.h>
2809ea33e5SIgor M. Liplianin 
2909ea33e5SIgor M. Liplianin #include "dvb_frontend.h"
3009ea33e5SIgor M. Liplianin #include "ds3000.h"
3109ea33e5SIgor M. Liplianin 
3209ea33e5SIgor M. Liplianin static int debug;
3309ea33e5SIgor M. Liplianin 
3409ea33e5SIgor M. Liplianin #define dprintk(args...) \
3509ea33e5SIgor M. Liplianin 	do { \
3609ea33e5SIgor M. Liplianin 		if (debug) \
3709ea33e5SIgor M. Liplianin 			printk(args); \
3809ea33e5SIgor M. Liplianin 	} while (0)
3909ea33e5SIgor M. Liplianin 
4009ea33e5SIgor M. Liplianin /* as of March 2009 current DS3000 firmware version is 1.78 */
4109ea33e5SIgor M. Liplianin /* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */
4209ea33e5SIgor M. Liplianin #define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw"
4309ea33e5SIgor M. Liplianin 
4409ea33e5SIgor M. Liplianin #define DS3000_SAMPLE_RATE 96000 /* in kHz */
4509ea33e5SIgor M. Liplianin 
4609ea33e5SIgor M. Liplianin /* Register values to initialise the demod in DVB-S mode */
4709ea33e5SIgor M. Liplianin static u8 ds3000_dvbs_init_tab[] = {
4809ea33e5SIgor M. Liplianin 	0x23, 0x05,
4909ea33e5SIgor M. Liplianin 	0x08, 0x03,
5009ea33e5SIgor M. Liplianin 	0x0c, 0x00,
5109ea33e5SIgor M. Liplianin 	0x21, 0x54,
5209ea33e5SIgor M. Liplianin 	0x25, 0x82,
5309ea33e5SIgor M. Liplianin 	0x27, 0x31,
5409ea33e5SIgor M. Liplianin 	0x30, 0x08,
5509ea33e5SIgor M. Liplianin 	0x31, 0x40,
5609ea33e5SIgor M. Liplianin 	0x32, 0x32,
5709ea33e5SIgor M. Liplianin 	0x33, 0x35,
5809ea33e5SIgor M. Liplianin 	0x35, 0xff,
5909ea33e5SIgor M. Liplianin 	0x3a, 0x00,
6009ea33e5SIgor M. Liplianin 	0x37, 0x10,
6109ea33e5SIgor M. Liplianin 	0x38, 0x10,
6209ea33e5SIgor M. Liplianin 	0x39, 0x02,
6309ea33e5SIgor M. Liplianin 	0x42, 0x60,
6409ea33e5SIgor M. Liplianin 	0x4a, 0x40,
6509ea33e5SIgor M. Liplianin 	0x4b, 0x04,
6609ea33e5SIgor M. Liplianin 	0x4d, 0x91,
6709ea33e5SIgor M. Liplianin 	0x5d, 0xc8,
6809ea33e5SIgor M. Liplianin 	0x50, 0x77,
6909ea33e5SIgor M. Liplianin 	0x51, 0x77,
7009ea33e5SIgor M. Liplianin 	0x52, 0x36,
7109ea33e5SIgor M. Liplianin 	0x53, 0x36,
7209ea33e5SIgor M. Liplianin 	0x56, 0x01,
7309ea33e5SIgor M. Liplianin 	0x63, 0x43,
7409ea33e5SIgor M. Liplianin 	0x64, 0x30,
7509ea33e5SIgor M. Liplianin 	0x65, 0x40,
7609ea33e5SIgor M. Liplianin 	0x68, 0x26,
7709ea33e5SIgor M. Liplianin 	0x69, 0x4c,
7809ea33e5SIgor M. Liplianin 	0x70, 0x20,
7909ea33e5SIgor M. Liplianin 	0x71, 0x70,
8009ea33e5SIgor M. Liplianin 	0x72, 0x04,
8109ea33e5SIgor M. Liplianin 	0x73, 0x00,
8209ea33e5SIgor M. Liplianin 	0x70, 0x40,
8309ea33e5SIgor M. Liplianin 	0x71, 0x70,
8409ea33e5SIgor M. Liplianin 	0x72, 0x04,
8509ea33e5SIgor M. Liplianin 	0x73, 0x00,
8609ea33e5SIgor M. Liplianin 	0x70, 0x60,
8709ea33e5SIgor M. Liplianin 	0x71, 0x70,
8809ea33e5SIgor M. Liplianin 	0x72, 0x04,
8909ea33e5SIgor M. Liplianin 	0x73, 0x00,
9009ea33e5SIgor M. Liplianin 	0x70, 0x80,
9109ea33e5SIgor M. Liplianin 	0x71, 0x70,
9209ea33e5SIgor M. Liplianin 	0x72, 0x04,
9309ea33e5SIgor M. Liplianin 	0x73, 0x00,
9409ea33e5SIgor M. Liplianin 	0x70, 0xa0,
9509ea33e5SIgor M. Liplianin 	0x71, 0x70,
9609ea33e5SIgor M. Liplianin 	0x72, 0x04,
9709ea33e5SIgor M. Liplianin 	0x73, 0x00,
9809ea33e5SIgor M. Liplianin 	0x70, 0x1f,
9909ea33e5SIgor M. Liplianin 	0x76, 0x00,
10009ea33e5SIgor M. Liplianin 	0x77, 0xd1,
10109ea33e5SIgor M. Liplianin 	0x78, 0x0c,
10209ea33e5SIgor M. Liplianin 	0x79, 0x80,
10309ea33e5SIgor M. Liplianin 	0x7f, 0x04,
10409ea33e5SIgor M. Liplianin 	0x7c, 0x00,
10509ea33e5SIgor M. Liplianin 	0x80, 0x86,
10609ea33e5SIgor M. Liplianin 	0x81, 0xa6,
10709ea33e5SIgor M. Liplianin 	0x85, 0x04,
10809ea33e5SIgor M. Liplianin 	0xcd, 0xf4,
10909ea33e5SIgor M. Liplianin 	0x90, 0x33,
11009ea33e5SIgor M. Liplianin 	0xa0, 0x44,
11109ea33e5SIgor M. Liplianin 	0xc0, 0x18,
11209ea33e5SIgor M. Liplianin 	0xc3, 0x10,
11309ea33e5SIgor M. Liplianin 	0xc4, 0x08,
11409ea33e5SIgor M. Liplianin 	0xc5, 0x80,
11509ea33e5SIgor M. Liplianin 	0xc6, 0x80,
11609ea33e5SIgor M. Liplianin 	0xc7, 0x0a,
11709ea33e5SIgor M. Liplianin 	0xc8, 0x1a,
11809ea33e5SIgor M. Liplianin 	0xc9, 0x80,
11909ea33e5SIgor M. Liplianin 	0xfe, 0x92,
12009ea33e5SIgor M. Liplianin 	0xe0, 0xf8,
12109ea33e5SIgor M. Liplianin 	0xe6, 0x8b,
12209ea33e5SIgor M. Liplianin 	0xd0, 0x40,
12309ea33e5SIgor M. Liplianin 	0xf8, 0x20,
12409ea33e5SIgor M. Liplianin 	0xfa, 0x0f,
12509ea33e5SIgor M. Liplianin 	0xfd, 0x20,
12609ea33e5SIgor M. Liplianin 	0xad, 0x20,
12709ea33e5SIgor M. Liplianin 	0xae, 0x07,
12809ea33e5SIgor M. Liplianin 	0xb8, 0x00,
12909ea33e5SIgor M. Liplianin };
13009ea33e5SIgor M. Liplianin 
13109ea33e5SIgor M. Liplianin /* Register values to initialise the demod in DVB-S2 mode */
13209ea33e5SIgor M. Liplianin static u8 ds3000_dvbs2_init_tab[] = {
13309ea33e5SIgor M. Liplianin 	0x23, 0x0f,
13409ea33e5SIgor M. Liplianin 	0x08, 0x07,
13509ea33e5SIgor M. Liplianin 	0x0c, 0x00,
13609ea33e5SIgor M. Liplianin 	0x21, 0x54,
13709ea33e5SIgor M. Liplianin 	0x25, 0x82,
13809ea33e5SIgor M. Liplianin 	0x27, 0x31,
13909ea33e5SIgor M. Liplianin 	0x30, 0x08,
14009ea33e5SIgor M. Liplianin 	0x31, 0x32,
14109ea33e5SIgor M. Liplianin 	0x32, 0x32,
14209ea33e5SIgor M. Liplianin 	0x33, 0x35,
14309ea33e5SIgor M. Liplianin 	0x35, 0xff,
14409ea33e5SIgor M. Liplianin 	0x3a, 0x00,
14509ea33e5SIgor M. Liplianin 	0x37, 0x10,
14609ea33e5SIgor M. Liplianin 	0x38, 0x10,
14709ea33e5SIgor M. Liplianin 	0x39, 0x02,
14809ea33e5SIgor M. Liplianin 	0x42, 0x60,
14909ea33e5SIgor M. Liplianin 	0x4a, 0x80,
15009ea33e5SIgor M. Liplianin 	0x4b, 0x04,
15109ea33e5SIgor M. Liplianin 	0x4d, 0x81,
15209ea33e5SIgor M. Liplianin 	0x5d, 0x88,
15309ea33e5SIgor M. Liplianin 	0x50, 0x36,
15409ea33e5SIgor M. Liplianin 	0x51, 0x36,
15509ea33e5SIgor M. Liplianin 	0x52, 0x36,
15609ea33e5SIgor M. Liplianin 	0x53, 0x36,
15709ea33e5SIgor M. Liplianin 	0x63, 0x60,
15809ea33e5SIgor M. Liplianin 	0x64, 0x10,
15909ea33e5SIgor M. Liplianin 	0x65, 0x10,
16009ea33e5SIgor M. Liplianin 	0x68, 0x04,
16109ea33e5SIgor M. Liplianin 	0x69, 0x29,
16209ea33e5SIgor M. Liplianin 	0x70, 0x20,
16309ea33e5SIgor M. Liplianin 	0x71, 0x70,
16409ea33e5SIgor M. Liplianin 	0x72, 0x04,
16509ea33e5SIgor M. Liplianin 	0x73, 0x00,
16609ea33e5SIgor M. Liplianin 	0x70, 0x40,
16709ea33e5SIgor M. Liplianin 	0x71, 0x70,
16809ea33e5SIgor M. Liplianin 	0x72, 0x04,
16909ea33e5SIgor M. Liplianin 	0x73, 0x00,
17009ea33e5SIgor M. Liplianin 	0x70, 0x60,
17109ea33e5SIgor M. Liplianin 	0x71, 0x70,
17209ea33e5SIgor M. Liplianin 	0x72, 0x04,
17309ea33e5SIgor M. Liplianin 	0x73, 0x00,
17409ea33e5SIgor M. Liplianin 	0x70, 0x80,
17509ea33e5SIgor M. Liplianin 	0x71, 0x70,
17609ea33e5SIgor M. Liplianin 	0x72, 0x04,
17709ea33e5SIgor M. Liplianin 	0x73, 0x00,
17809ea33e5SIgor M. Liplianin 	0x70, 0xa0,
17909ea33e5SIgor M. Liplianin 	0x71, 0x70,
18009ea33e5SIgor M. Liplianin 	0x72, 0x04,
18109ea33e5SIgor M. Liplianin 	0x73, 0x00,
18209ea33e5SIgor M. Liplianin 	0x70, 0x1f,
18309ea33e5SIgor M. Liplianin 	0xa0, 0x44,
18409ea33e5SIgor M. Liplianin 	0xc0, 0x08,
18509ea33e5SIgor M. Liplianin 	0xc1, 0x10,
18609ea33e5SIgor M. Liplianin 	0xc2, 0x08,
18709ea33e5SIgor M. Liplianin 	0xc3, 0x10,
18809ea33e5SIgor M. Liplianin 	0xc4, 0x08,
18909ea33e5SIgor M. Liplianin 	0xc5, 0xf0,
19009ea33e5SIgor M. Liplianin 	0xc6, 0xf0,
19109ea33e5SIgor M. Liplianin 	0xc7, 0x0a,
19209ea33e5SIgor M. Liplianin 	0xc8, 0x1a,
19309ea33e5SIgor M. Liplianin 	0xc9, 0x80,
19409ea33e5SIgor M. Liplianin 	0xca, 0x23,
19509ea33e5SIgor M. Liplianin 	0xcb, 0x24,
19609ea33e5SIgor M. Liplianin 	0xce, 0x74,
19709ea33e5SIgor M. Liplianin 	0x90, 0x03,
19809ea33e5SIgor M. Liplianin 	0x76, 0x80,
19909ea33e5SIgor M. Liplianin 	0x77, 0x42,
20009ea33e5SIgor M. Liplianin 	0x78, 0x0a,
20109ea33e5SIgor M. Liplianin 	0x79, 0x80,
20209ea33e5SIgor M. Liplianin 	0xad, 0x40,
20309ea33e5SIgor M. Liplianin 	0xae, 0x07,
20409ea33e5SIgor M. Liplianin 	0x7f, 0xd4,
20509ea33e5SIgor M. Liplianin 	0x7c, 0x00,
20609ea33e5SIgor M. Liplianin 	0x80, 0xa8,
20709ea33e5SIgor M. Liplianin 	0x81, 0xda,
20809ea33e5SIgor M. Liplianin 	0x7c, 0x01,
20909ea33e5SIgor M. Liplianin 	0x80, 0xda,
21009ea33e5SIgor M. Liplianin 	0x81, 0xec,
21109ea33e5SIgor M. Liplianin 	0x7c, 0x02,
21209ea33e5SIgor M. Liplianin 	0x80, 0xca,
21309ea33e5SIgor M. Liplianin 	0x81, 0xeb,
21409ea33e5SIgor M. Liplianin 	0x7c, 0x03,
21509ea33e5SIgor M. Liplianin 	0x80, 0xba,
21609ea33e5SIgor M. Liplianin 	0x81, 0xdb,
21709ea33e5SIgor M. Liplianin 	0x85, 0x08,
21809ea33e5SIgor M. Liplianin 	0x86, 0x00,
21909ea33e5SIgor M. Liplianin 	0x87, 0x02,
22009ea33e5SIgor M. Liplianin 	0x89, 0x80,
22109ea33e5SIgor M. Liplianin 	0x8b, 0x44,
22209ea33e5SIgor M. Liplianin 	0x8c, 0xaa,
22309ea33e5SIgor M. Liplianin 	0x8a, 0x10,
22409ea33e5SIgor M. Liplianin 	0xba, 0x00,
22509ea33e5SIgor M. Liplianin 	0xf5, 0x04,
22609ea33e5SIgor M. Liplianin 	0xfe, 0x44,
22709ea33e5SIgor M. Liplianin 	0xd2, 0x32,
22809ea33e5SIgor M. Liplianin 	0xb8, 0x00,
22909ea33e5SIgor M. Liplianin };
23009ea33e5SIgor M. Liplianin 
23109ea33e5SIgor M. Liplianin struct ds3000_state {
23209ea33e5SIgor M. Liplianin 	struct i2c_adapter *i2c;
23309ea33e5SIgor M. Liplianin 	const struct ds3000_config *config;
23409ea33e5SIgor M. Liplianin 	struct dvb_frontend frontend;
23509ea33e5SIgor M. Liplianin 	/* previous uncorrected block counter for DVB-S2 */
23609ea33e5SIgor M. Liplianin 	u16 prevUCBS2;
23709ea33e5SIgor M. Liplianin };
23809ea33e5SIgor M. Liplianin 
23909ea33e5SIgor M. Liplianin static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
24009ea33e5SIgor M. Liplianin {
24109ea33e5SIgor M. Liplianin 	u8 buf[] = { reg, data };
24209ea33e5SIgor M. Liplianin 	struct i2c_msg msg = { .addr = state->config->demod_address,
24309ea33e5SIgor M. Liplianin 		.flags = 0, .buf = buf, .len = 2 };
24409ea33e5SIgor M. Liplianin 	int err;
24509ea33e5SIgor M. Liplianin 
24609ea33e5SIgor M. Liplianin 	dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
24709ea33e5SIgor M. Liplianin 
24809ea33e5SIgor M. Liplianin 	err = i2c_transfer(state->i2c, &msg, 1);
24909ea33e5SIgor M. Liplianin 	if (err != 1) {
25009ea33e5SIgor M. Liplianin 		printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
25109ea33e5SIgor M. Liplianin 			 " value == 0x%02x)\n", __func__, err, reg, data);
25209ea33e5SIgor M. Liplianin 		return -EREMOTEIO;
25309ea33e5SIgor M. Liplianin 	}
25409ea33e5SIgor M. Liplianin 
25509ea33e5SIgor M. Liplianin 	return 0;
25609ea33e5SIgor M. Liplianin }
25709ea33e5SIgor M. Liplianin 
258*c1965eaeSKonstantin Dimitrov static int ds3000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
25909ea33e5SIgor M. Liplianin {
260*c1965eaeSKonstantin Dimitrov 	struct ds3000_state *state = fe->demodulator_priv;
26109ea33e5SIgor M. Liplianin 
262*c1965eaeSKonstantin Dimitrov 	if (enable)
263*c1965eaeSKonstantin Dimitrov 		ds3000_writereg(state, 0x03, 0x12);
264*c1965eaeSKonstantin Dimitrov 	else
265*c1965eaeSKonstantin Dimitrov 		ds3000_writereg(state, 0x03, 0x02);
26609ea33e5SIgor M. Liplianin 
26709ea33e5SIgor M. Liplianin 	return 0;
26809ea33e5SIgor M. Liplianin }
26909ea33e5SIgor M. Liplianin 
27009ea33e5SIgor M. Liplianin /* I2C write for 8k firmware load */
27109ea33e5SIgor M. Liplianin static int ds3000_writeFW(struct ds3000_state *state, int reg,
27209ea33e5SIgor M. Liplianin 				const u8 *data, u16 len)
27309ea33e5SIgor M. Liplianin {
27409ea33e5SIgor M. Liplianin 	int i, ret = -EREMOTEIO;
27509ea33e5SIgor M. Liplianin 	struct i2c_msg msg;
27609ea33e5SIgor M. Liplianin 	u8 *buf;
27709ea33e5SIgor M. Liplianin 
278caa687c8SIgor M. Liplianin 	buf = kmalloc(33, GFP_KERNEL);
27909ea33e5SIgor M. Liplianin 	if (buf == NULL) {
28009ea33e5SIgor M. Liplianin 		printk(KERN_ERR "Unable to kmalloc\n");
28109ea33e5SIgor M. Liplianin 		ret = -ENOMEM;
28209ea33e5SIgor M. Liplianin 		goto error;
28309ea33e5SIgor M. Liplianin 	}
28409ea33e5SIgor M. Liplianin 
28509ea33e5SIgor M. Liplianin 	*(buf) = reg;
28609ea33e5SIgor M. Liplianin 
28709ea33e5SIgor M. Liplianin 	msg.addr = state->config->demod_address;
28809ea33e5SIgor M. Liplianin 	msg.flags = 0;
28909ea33e5SIgor M. Liplianin 	msg.buf = buf;
290caa687c8SIgor M. Liplianin 	msg.len = 33;
29109ea33e5SIgor M. Liplianin 
292caa687c8SIgor M. Liplianin 	for (i = 0; i < len; i += 32) {
293caa687c8SIgor M. Liplianin 		memcpy(buf + 1, data + i, 32);
29409ea33e5SIgor M. Liplianin 
29509ea33e5SIgor M. Liplianin 		dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
29609ea33e5SIgor M. Liplianin 
29709ea33e5SIgor M. Liplianin 		ret = i2c_transfer(state->i2c, &msg, 1);
29809ea33e5SIgor M. Liplianin 		if (ret != 1) {
29909ea33e5SIgor M. Liplianin 			printk(KERN_ERR "%s: write error(err == %i, "
30009ea33e5SIgor M. Liplianin 				"reg == 0x%02x\n", __func__, ret, reg);
30109ea33e5SIgor M. Liplianin 			ret = -EREMOTEIO;
30209ea33e5SIgor M. Liplianin 		}
30309ea33e5SIgor M. Liplianin 	}
30409ea33e5SIgor M. Liplianin 
30509ea33e5SIgor M. Liplianin error:
30609ea33e5SIgor M. Liplianin 	kfree(buf);
30709ea33e5SIgor M. Liplianin 
30809ea33e5SIgor M. Liplianin 	return ret;
30909ea33e5SIgor M. Liplianin }
31009ea33e5SIgor M. Liplianin 
31109ea33e5SIgor M. Liplianin static int ds3000_readreg(struct ds3000_state *state, u8 reg)
31209ea33e5SIgor M. Liplianin {
31309ea33e5SIgor M. Liplianin 	int ret;
31409ea33e5SIgor M. Liplianin 	u8 b0[] = { reg };
31509ea33e5SIgor M. Liplianin 	u8 b1[] = { 0 };
31609ea33e5SIgor M. Liplianin 	struct i2c_msg msg[] = {
31709ea33e5SIgor M. Liplianin 		{
31809ea33e5SIgor M. Liplianin 			.addr = state->config->demod_address,
31909ea33e5SIgor M. Liplianin 			.flags = 0,
32009ea33e5SIgor M. Liplianin 			.buf = b0,
32109ea33e5SIgor M. Liplianin 			.len = 1
32209ea33e5SIgor M. Liplianin 		}, {
32309ea33e5SIgor M. Liplianin 			.addr = state->config->demod_address,
32409ea33e5SIgor M. Liplianin 			.flags = I2C_M_RD,
32509ea33e5SIgor M. Liplianin 			.buf = b1,
32609ea33e5SIgor M. Liplianin 			.len = 1
32709ea33e5SIgor M. Liplianin 		}
32809ea33e5SIgor M. Liplianin 	};
32909ea33e5SIgor M. Liplianin 
33009ea33e5SIgor M. Liplianin 	ret = i2c_transfer(state->i2c, msg, 2);
33109ea33e5SIgor M. Liplianin 
33209ea33e5SIgor M. Liplianin 	if (ret != 2) {
33309ea33e5SIgor M. Liplianin 		printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
33409ea33e5SIgor M. Liplianin 		return ret;
33509ea33e5SIgor M. Liplianin 	}
33609ea33e5SIgor M. Liplianin 
33709ea33e5SIgor M. Liplianin 	dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
33809ea33e5SIgor M. Liplianin 
33909ea33e5SIgor M. Liplianin 	return b1[0];
34009ea33e5SIgor M. Liplianin }
34109ea33e5SIgor M. Liplianin 
34209ea33e5SIgor M. Liplianin static int ds3000_load_firmware(struct dvb_frontend *fe,
34309ea33e5SIgor M. Liplianin 					const struct firmware *fw);
34409ea33e5SIgor M. Liplianin 
34509ea33e5SIgor M. Liplianin static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
34609ea33e5SIgor M. Liplianin {
34709ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
34809ea33e5SIgor M. Liplianin 	const struct firmware *fw;
34909ea33e5SIgor M. Liplianin 	int ret = 0;
35009ea33e5SIgor M. Liplianin 
35109ea33e5SIgor M. Liplianin 	dprintk("%s()\n", __func__);
35209ea33e5SIgor M. Liplianin 
353034351ffSRémi Cardona 	ret = ds3000_readreg(state, 0xb2);
354034351ffSRémi Cardona 	if (ret < 0)
35509ea33e5SIgor M. Liplianin 		return ret;
35609ea33e5SIgor M. Liplianin 
35709ea33e5SIgor M. Liplianin 	/* Load firmware */
35809ea33e5SIgor M. Liplianin 	/* request the firmware, this will block until someone uploads it */
35909ea33e5SIgor M. Liplianin 	printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
36009ea33e5SIgor M. Liplianin 				DS3000_DEFAULT_FIRMWARE);
36109ea33e5SIgor M. Liplianin 	ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
36209ea33e5SIgor M. Liplianin 				state->i2c->dev.parent);
36309ea33e5SIgor M. Liplianin 	printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
36409ea33e5SIgor M. Liplianin 	if (ret) {
36509ea33e5SIgor M. Liplianin 		printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
36609ea33e5SIgor M. Liplianin 				"found?)\n", __func__);
36709ea33e5SIgor M. Liplianin 		return ret;
36809ea33e5SIgor M. Liplianin 	}
36909ea33e5SIgor M. Liplianin 
37009ea33e5SIgor M. Liplianin 	ret = ds3000_load_firmware(fe, fw);
37109ea33e5SIgor M. Liplianin 	if (ret)
37209ea33e5SIgor M. Liplianin 		printk("%s: Writing firmware to device failed\n", __func__);
37309ea33e5SIgor M. Liplianin 
37409ea33e5SIgor M. Liplianin 	release_firmware(fw);
37509ea33e5SIgor M. Liplianin 
37609ea33e5SIgor M. Liplianin 	dprintk("%s: Firmware upload %s\n", __func__,
37709ea33e5SIgor M. Liplianin 			ret == 0 ? "complete" : "failed");
37809ea33e5SIgor M. Liplianin 
37909ea33e5SIgor M. Liplianin 	return ret;
38009ea33e5SIgor M. Liplianin }
38109ea33e5SIgor M. Liplianin 
38209ea33e5SIgor M. Liplianin static int ds3000_load_firmware(struct dvb_frontend *fe,
38309ea33e5SIgor M. Liplianin 					const struct firmware *fw)
38409ea33e5SIgor M. Liplianin {
38509ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
38609ea33e5SIgor M. Liplianin 
38709ea33e5SIgor M. Liplianin 	dprintk("%s\n", __func__);
38809ea33e5SIgor M. Liplianin 	dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
38909ea33e5SIgor M. Liplianin 			fw->size,
39009ea33e5SIgor M. Liplianin 			fw->data[0],
39109ea33e5SIgor M. Liplianin 			fw->data[1],
39209ea33e5SIgor M. Liplianin 			fw->data[fw->size - 2],
39309ea33e5SIgor M. Liplianin 			fw->data[fw->size - 1]);
39409ea33e5SIgor M. Liplianin 
39509ea33e5SIgor M. Liplianin 	/* Begin the firmware load process */
39609ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xb2, 0x01);
39709ea33e5SIgor M. Liplianin 	/* write the entire firmware */
39809ea33e5SIgor M. Liplianin 	ds3000_writeFW(state, 0xb0, fw->data, fw->size);
39909ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xb2, 0x00);
40009ea33e5SIgor M. Liplianin 
40109ea33e5SIgor M. Liplianin 	return 0;
40209ea33e5SIgor M. Liplianin }
40309ea33e5SIgor M. Liplianin 
404d2ffc447SIgor M. Liplianin static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
405d2ffc447SIgor M. Liplianin {
406d2ffc447SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
407d2ffc447SIgor M. Liplianin 	u8 data;
408d2ffc447SIgor M. Liplianin 
409d2ffc447SIgor M. Liplianin 	dprintk("%s(%d)\n", __func__, voltage);
410d2ffc447SIgor M. Liplianin 
411d2ffc447SIgor M. Liplianin 	data = ds3000_readreg(state, 0xa2);
412d2ffc447SIgor M. Liplianin 	data |= 0x03; /* bit0 V/H, bit1 off/on */
413d2ffc447SIgor M. Liplianin 
414d2ffc447SIgor M. Liplianin 	switch (voltage) {
415d2ffc447SIgor M. Liplianin 	case SEC_VOLTAGE_18:
416d2ffc447SIgor M. Liplianin 		data &= ~0x03;
417d2ffc447SIgor M. Liplianin 		break;
418d2ffc447SIgor M. Liplianin 	case SEC_VOLTAGE_13:
419d2ffc447SIgor M. Liplianin 		data &= ~0x03;
420d2ffc447SIgor M. Liplianin 		data |= 0x01;
421d2ffc447SIgor M. Liplianin 		break;
422d2ffc447SIgor M. Liplianin 	case SEC_VOLTAGE_OFF:
423d2ffc447SIgor M. Liplianin 		break;
424d2ffc447SIgor M. Liplianin 	}
425d2ffc447SIgor M. Liplianin 
426d2ffc447SIgor M. Liplianin 	ds3000_writereg(state, 0xa2, data);
427d2ffc447SIgor M. Liplianin 
428d2ffc447SIgor M. Liplianin 	return 0;
429d2ffc447SIgor M. Liplianin }
430d2ffc447SIgor M. Liplianin 
43109ea33e5SIgor M. Liplianin static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
43209ea33e5SIgor M. Liplianin {
43309ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
43409ea33e5SIgor M. Liplianin 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
43509ea33e5SIgor M. Liplianin 	int lock;
43609ea33e5SIgor M. Liplianin 
43709ea33e5SIgor M. Liplianin 	*status = 0;
43809ea33e5SIgor M. Liplianin 
43909ea33e5SIgor M. Liplianin 	switch (c->delivery_system) {
44009ea33e5SIgor M. Liplianin 	case SYS_DVBS:
44109ea33e5SIgor M. Liplianin 		lock = ds3000_readreg(state, 0xd1);
44209ea33e5SIgor M. Liplianin 		if ((lock & 0x07) == 0x07)
44309ea33e5SIgor M. Liplianin 			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
44409ea33e5SIgor M. Liplianin 				FE_HAS_VITERBI | FE_HAS_SYNC |
44509ea33e5SIgor M. Liplianin 				FE_HAS_LOCK;
44609ea33e5SIgor M. Liplianin 
44709ea33e5SIgor M. Liplianin 		break;
44809ea33e5SIgor M. Liplianin 	case SYS_DVBS2:
44909ea33e5SIgor M. Liplianin 		lock = ds3000_readreg(state, 0x0d);
45009ea33e5SIgor M. Liplianin 		if ((lock & 0x8f) == 0x8f)
45109ea33e5SIgor M. Liplianin 			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
45209ea33e5SIgor M. Liplianin 				FE_HAS_VITERBI | FE_HAS_SYNC |
45309ea33e5SIgor M. Liplianin 				FE_HAS_LOCK;
45409ea33e5SIgor M. Liplianin 
45509ea33e5SIgor M. Liplianin 		break;
45609ea33e5SIgor M. Liplianin 	default:
45709ea33e5SIgor M. Liplianin 		return 1;
45809ea33e5SIgor M. Liplianin 	}
45909ea33e5SIgor M. Liplianin 
46009ea33e5SIgor M. Liplianin 	dprintk("%s: status = 0x%02x\n", __func__, lock);
46109ea33e5SIgor M. Liplianin 
46209ea33e5SIgor M. Liplianin 	return 0;
46309ea33e5SIgor M. Liplianin }
46409ea33e5SIgor M. Liplianin 
46509ea33e5SIgor M. Liplianin /* read DS3000 BER value */
46609ea33e5SIgor M. Liplianin static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
46709ea33e5SIgor M. Liplianin {
46809ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
46909ea33e5SIgor M. Liplianin 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
47009ea33e5SIgor M. Liplianin 	u8 data;
47109ea33e5SIgor M. Liplianin 	u32 ber_reading, lpdc_frames;
47209ea33e5SIgor M. Liplianin 
47309ea33e5SIgor M. Liplianin 	dprintk("%s()\n", __func__);
47409ea33e5SIgor M. Liplianin 
47509ea33e5SIgor M. Liplianin 	switch (c->delivery_system) {
47609ea33e5SIgor M. Liplianin 	case SYS_DVBS:
47709ea33e5SIgor M. Liplianin 		/* set the number of bytes checked during
47809ea33e5SIgor M. Liplianin 		BER estimation */
47909ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xf9, 0x04);
48009ea33e5SIgor M. Liplianin 		/* read BER estimation status */
48109ea33e5SIgor M. Liplianin 		data = ds3000_readreg(state, 0xf8);
48209ea33e5SIgor M. Liplianin 		/* check if BER estimation is ready */
48309ea33e5SIgor M. Liplianin 		if ((data & 0x10) == 0) {
48409ea33e5SIgor M. Liplianin 			/* this is the number of error bits,
48509ea33e5SIgor M. Liplianin 			to calculate the bit error rate
48609ea33e5SIgor M. Liplianin 			divide to 8388608 */
48709ea33e5SIgor M. Liplianin 			*ber = (ds3000_readreg(state, 0xf7) << 8) |
48809ea33e5SIgor M. Liplianin 				ds3000_readreg(state, 0xf6);
48909ea33e5SIgor M. Liplianin 			/* start counting error bits */
49009ea33e5SIgor M. Liplianin 			/* need to be set twice
49109ea33e5SIgor M. Liplianin 			otherwise it fails sometimes */
49209ea33e5SIgor M. Liplianin 			data |= 0x10;
49309ea33e5SIgor M. Liplianin 			ds3000_writereg(state, 0xf8, data);
49409ea33e5SIgor M. Liplianin 			ds3000_writereg(state, 0xf8, data);
49509ea33e5SIgor M. Liplianin 		} else
49609ea33e5SIgor M. Liplianin 			/* used to indicate that BER estimation
49709ea33e5SIgor M. Liplianin 			is not ready, i.e. BER is unknown */
49809ea33e5SIgor M. Liplianin 			*ber = 0xffffffff;
49909ea33e5SIgor M. Liplianin 		break;
50009ea33e5SIgor M. Liplianin 	case SYS_DVBS2:
50109ea33e5SIgor M. Liplianin 		/* read the number of LPDC decoded frames */
50209ea33e5SIgor M. Liplianin 		lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) |
50309ea33e5SIgor M. Liplianin 				(ds3000_readreg(state, 0xd6) << 8) |
50409ea33e5SIgor M. Liplianin 				ds3000_readreg(state, 0xd5);
50509ea33e5SIgor M. Liplianin 		/* read the number of packets with bad CRC */
50609ea33e5SIgor M. Liplianin 		ber_reading = (ds3000_readreg(state, 0xf8) << 8) |
50709ea33e5SIgor M. Liplianin 				ds3000_readreg(state, 0xf7);
50809ea33e5SIgor M. Liplianin 		if (lpdc_frames > 750) {
50909ea33e5SIgor M. Liplianin 			/* clear LPDC frame counters */
51009ea33e5SIgor M. Liplianin 			ds3000_writereg(state, 0xd1, 0x01);
51109ea33e5SIgor M. Liplianin 			/* clear bad packets counter */
51209ea33e5SIgor M. Liplianin 			ds3000_writereg(state, 0xf9, 0x01);
51309ea33e5SIgor M. Liplianin 			/* enable bad packets counter */
51409ea33e5SIgor M. Liplianin 			ds3000_writereg(state, 0xf9, 0x00);
51509ea33e5SIgor M. Liplianin 			/* enable LPDC frame counters */
51609ea33e5SIgor M. Liplianin 			ds3000_writereg(state, 0xd1, 0x00);
51709ea33e5SIgor M. Liplianin 			*ber = ber_reading;
51809ea33e5SIgor M. Liplianin 		} else
51909ea33e5SIgor M. Liplianin 			/* used to indicate that BER estimation is not ready,
52009ea33e5SIgor M. Liplianin 			i.e. BER is unknown */
52109ea33e5SIgor M. Liplianin 			*ber = 0xffffffff;
52209ea33e5SIgor M. Liplianin 		break;
52309ea33e5SIgor M. Liplianin 	default:
52409ea33e5SIgor M. Liplianin 		return 1;
52509ea33e5SIgor M. Liplianin 	}
52609ea33e5SIgor M. Liplianin 
52709ea33e5SIgor M. Liplianin 	return 0;
52809ea33e5SIgor M. Liplianin }
52909ea33e5SIgor M. Liplianin 
53009ea33e5SIgor M. Liplianin /* calculate DS3000 snr value in dB */
53109ea33e5SIgor M. Liplianin static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
53209ea33e5SIgor M. Liplianin {
53309ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
53409ea33e5SIgor M. Liplianin 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
53509ea33e5SIgor M. Liplianin 	u8 snr_reading, snr_value;
53609ea33e5SIgor M. Liplianin 	u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp;
53709ea33e5SIgor M. Liplianin 	static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */
53809ea33e5SIgor M. Liplianin 		0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03,
53909ea33e5SIgor M. Liplianin 		0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717,
54009ea33e5SIgor M. Liplianin 		0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505
54109ea33e5SIgor M. Liplianin 	};
54209ea33e5SIgor M. Liplianin 	static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */
54309ea33e5SIgor M. Liplianin 		0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103,
54409ea33e5SIgor M. Liplianin 		0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5,
54509ea33e5SIgor M. Liplianin 		0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6,
54609ea33e5SIgor M. Liplianin 		0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888,
54709ea33e5SIgor M. Liplianin 		0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51,
54809ea33e5SIgor M. Liplianin 		0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68,
54909ea33e5SIgor M. Liplianin 		0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206,
55009ea33e5SIgor M. Liplianin 		0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a,
55109ea33e5SIgor M. Liplianin 		0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649,
55209ea33e5SIgor M. Liplianin 		0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813,
55309ea33e5SIgor M. Liplianin 		0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1,
55409ea33e5SIgor M. Liplianin 		0x49e9, 0x4a20, 0x4a57
55509ea33e5SIgor M. Liplianin 	};
55609ea33e5SIgor M. Liplianin 
55709ea33e5SIgor M. Liplianin 	dprintk("%s()\n", __func__);
55809ea33e5SIgor M. Liplianin 
55909ea33e5SIgor M. Liplianin 	switch (c->delivery_system) {
56009ea33e5SIgor M. Liplianin 	case SYS_DVBS:
56109ea33e5SIgor M. Liplianin 		snr_reading = ds3000_readreg(state, 0xff);
56209ea33e5SIgor M. Liplianin 		snr_reading /= 8;
56309ea33e5SIgor M. Liplianin 		if (snr_reading == 0)
56409ea33e5SIgor M. Liplianin 			*snr = 0x0000;
56509ea33e5SIgor M. Liplianin 		else {
56609ea33e5SIgor M. Liplianin 			if (snr_reading > 20)
56709ea33e5SIgor M. Liplianin 				snr_reading = 20;
56809ea33e5SIgor M. Liplianin 			snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026;
56909ea33e5SIgor M. Liplianin 			/* cook the value to be suitable for szap-s2
57009ea33e5SIgor M. Liplianin 			human readable output */
57109ea33e5SIgor M. Liplianin 			*snr = snr_value * 8 * 655;
57209ea33e5SIgor M. Liplianin 		}
57309ea33e5SIgor M. Liplianin 		dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
57409ea33e5SIgor M. Liplianin 				snr_reading, *snr);
57509ea33e5SIgor M. Liplianin 		break;
57609ea33e5SIgor M. Liplianin 	case SYS_DVBS2:
57709ea33e5SIgor M. Liplianin 		dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) +
57809ea33e5SIgor M. Liplianin 				(ds3000_readreg(state, 0x8d) << 4);
57909ea33e5SIgor M. Liplianin 		dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
58009ea33e5SIgor M. Liplianin 		tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
581450df222SNicolas Noirbent 		if (tmp == 0) {
58209ea33e5SIgor M. Liplianin 			*snr = 0x0000;
58309ea33e5SIgor M. Liplianin 			return 0;
58409ea33e5SIgor M. Liplianin 		}
58509ea33e5SIgor M. Liplianin 		if (dvbs2_noise_reading == 0) {
58609ea33e5SIgor M. Liplianin 			snr_value = 0x0013;
58709ea33e5SIgor M. Liplianin 			/* cook the value to be suitable for szap-s2
58809ea33e5SIgor M. Liplianin 			human readable output */
58909ea33e5SIgor M. Liplianin 			*snr = 0xffff;
59009ea33e5SIgor M. Liplianin 			return 0;
59109ea33e5SIgor M. Liplianin 		}
59209ea33e5SIgor M. Liplianin 		if (tmp > dvbs2_noise_reading) {
59309ea33e5SIgor M. Liplianin 			snr_reading = tmp / dvbs2_noise_reading;
59409ea33e5SIgor M. Liplianin 			if (snr_reading > 80)
59509ea33e5SIgor M. Liplianin 				snr_reading = 80;
59609ea33e5SIgor M. Liplianin 			snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000;
59709ea33e5SIgor M. Liplianin 			/* cook the value to be suitable for szap-s2
59809ea33e5SIgor M. Liplianin 			human readable output */
59909ea33e5SIgor M. Liplianin 			*snr = snr_value * 5 * 655;
60009ea33e5SIgor M. Liplianin 		} else {
60109ea33e5SIgor M. Liplianin 			snr_reading = dvbs2_noise_reading / tmp;
60209ea33e5SIgor M. Liplianin 			if (snr_reading > 80)
60309ea33e5SIgor M. Liplianin 				snr_reading = 80;
60409ea33e5SIgor M. Liplianin 			*snr = -(dvbs2_snr_tab[snr_reading] / 1000);
60509ea33e5SIgor M. Liplianin 		}
60609ea33e5SIgor M. Liplianin 		dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
60709ea33e5SIgor M. Liplianin 				snr_reading, *snr);
60809ea33e5SIgor M. Liplianin 		break;
60909ea33e5SIgor M. Liplianin 	default:
61009ea33e5SIgor M. Liplianin 		return 1;
61109ea33e5SIgor M. Liplianin 	}
61209ea33e5SIgor M. Liplianin 
61309ea33e5SIgor M. Liplianin 	return 0;
61409ea33e5SIgor M. Liplianin }
61509ea33e5SIgor M. Liplianin 
61609ea33e5SIgor M. Liplianin /* read DS3000 uncorrected blocks */
61709ea33e5SIgor M. Liplianin static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
61809ea33e5SIgor M. Liplianin {
61909ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
62009ea33e5SIgor M. Liplianin 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
62109ea33e5SIgor M. Liplianin 	u8 data;
62209ea33e5SIgor M. Liplianin 	u16 _ucblocks;
62309ea33e5SIgor M. Liplianin 
62409ea33e5SIgor M. Liplianin 	dprintk("%s()\n", __func__);
62509ea33e5SIgor M. Liplianin 
62609ea33e5SIgor M. Liplianin 	switch (c->delivery_system) {
62709ea33e5SIgor M. Liplianin 	case SYS_DVBS:
62809ea33e5SIgor M. Liplianin 		*ucblocks = (ds3000_readreg(state, 0xf5) << 8) |
62909ea33e5SIgor M. Liplianin 				ds3000_readreg(state, 0xf4);
63009ea33e5SIgor M. Liplianin 		data = ds3000_readreg(state, 0xf8);
63109ea33e5SIgor M. Liplianin 		/* clear packet counters */
63209ea33e5SIgor M. Liplianin 		data &= ~0x20;
63309ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xf8, data);
63409ea33e5SIgor M. Liplianin 		/* enable packet counters */
63509ea33e5SIgor M. Liplianin 		data |= 0x20;
63609ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xf8, data);
63709ea33e5SIgor M. Liplianin 		break;
63809ea33e5SIgor M. Liplianin 	case SYS_DVBS2:
63909ea33e5SIgor M. Liplianin 		_ucblocks = (ds3000_readreg(state, 0xe2) << 8) |
64009ea33e5SIgor M. Liplianin 				ds3000_readreg(state, 0xe1);
64109ea33e5SIgor M. Liplianin 		if (_ucblocks > state->prevUCBS2)
64209ea33e5SIgor M. Liplianin 			*ucblocks = _ucblocks - state->prevUCBS2;
64309ea33e5SIgor M. Liplianin 		else
64409ea33e5SIgor M. Liplianin 			*ucblocks = state->prevUCBS2 - _ucblocks;
64509ea33e5SIgor M. Liplianin 		state->prevUCBS2 = _ucblocks;
64609ea33e5SIgor M. Liplianin 		break;
64709ea33e5SIgor M. Liplianin 	default:
64809ea33e5SIgor M. Liplianin 		return 1;
64909ea33e5SIgor M. Liplianin 	}
65009ea33e5SIgor M. Liplianin 
65109ea33e5SIgor M. Liplianin 	return 0;
65209ea33e5SIgor M. Liplianin }
65309ea33e5SIgor M. Liplianin 
65409ea33e5SIgor M. Liplianin static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
65509ea33e5SIgor M. Liplianin {
65609ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
65709ea33e5SIgor M. Liplianin 	u8 data;
65809ea33e5SIgor M. Liplianin 
65909ea33e5SIgor M. Liplianin 	dprintk("%s(%d)\n", __func__, tone);
66009ea33e5SIgor M. Liplianin 	if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
66109ea33e5SIgor M. Liplianin 		printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
66209ea33e5SIgor M. Liplianin 		return -EINVAL;
66309ea33e5SIgor M. Liplianin 	}
66409ea33e5SIgor M. Liplianin 
66509ea33e5SIgor M. Liplianin 	data = ds3000_readreg(state, 0xa2);
66609ea33e5SIgor M. Liplianin 	data &= ~0xc0;
66709ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xa2, data);
66809ea33e5SIgor M. Liplianin 
66909ea33e5SIgor M. Liplianin 	switch (tone) {
67009ea33e5SIgor M. Liplianin 	case SEC_TONE_ON:
67109ea33e5SIgor M. Liplianin 		dprintk("%s: setting tone on\n", __func__);
67209ea33e5SIgor M. Liplianin 		data = ds3000_readreg(state, 0xa1);
67309ea33e5SIgor M. Liplianin 		data &= ~0x43;
67409ea33e5SIgor M. Liplianin 		data |= 0x04;
67509ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xa1, data);
67609ea33e5SIgor M. Liplianin 		break;
67709ea33e5SIgor M. Liplianin 	case SEC_TONE_OFF:
67809ea33e5SIgor M. Liplianin 		dprintk("%s: setting tone off\n", __func__);
67909ea33e5SIgor M. Liplianin 		data = ds3000_readreg(state, 0xa2);
68009ea33e5SIgor M. Liplianin 		data |= 0x80;
68109ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xa2, data);
68209ea33e5SIgor M. Liplianin 		break;
68309ea33e5SIgor M. Liplianin 	}
68409ea33e5SIgor M. Liplianin 
68509ea33e5SIgor M. Liplianin 	return 0;
68609ea33e5SIgor M. Liplianin }
68709ea33e5SIgor M. Liplianin 
68809ea33e5SIgor M. Liplianin static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
68909ea33e5SIgor M. Liplianin 				struct dvb_diseqc_master_cmd *d)
69009ea33e5SIgor M. Liplianin {
69109ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
69209ea33e5SIgor M. Liplianin 	int i;
69309ea33e5SIgor M. Liplianin 	u8 data;
69409ea33e5SIgor M. Liplianin 
69509ea33e5SIgor M. Liplianin 	/* Dump DiSEqC message */
69609ea33e5SIgor M. Liplianin 	dprintk("%s(", __func__);
69709ea33e5SIgor M. Liplianin 	for (i = 0 ; i < d->msg_len;) {
69809ea33e5SIgor M. Liplianin 		dprintk("0x%02x", d->msg[i]);
69909ea33e5SIgor M. Liplianin 		if (++i < d->msg_len)
70009ea33e5SIgor M. Liplianin 			dprintk(", ");
70109ea33e5SIgor M. Liplianin 	}
70209ea33e5SIgor M. Liplianin 
70309ea33e5SIgor M. Liplianin 	/* enable DiSEqC message send pin */
70409ea33e5SIgor M. Liplianin 	data = ds3000_readreg(state, 0xa2);
70509ea33e5SIgor M. Liplianin 	data &= ~0xc0;
70609ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xa2, data);
70709ea33e5SIgor M. Liplianin 
70809ea33e5SIgor M. Liplianin 	/* DiSEqC message */
70909ea33e5SIgor M. Liplianin 	for (i = 0; i < d->msg_len; i++)
71009ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xa3 + i, d->msg[i]);
71109ea33e5SIgor M. Liplianin 
71209ea33e5SIgor M. Liplianin 	data = ds3000_readreg(state, 0xa1);
71309ea33e5SIgor M. Liplianin 	/* clear DiSEqC message length and status,
71409ea33e5SIgor M. Liplianin 	enable DiSEqC message send */
71509ea33e5SIgor M. Liplianin 	data &= ~0xf8;
71609ea33e5SIgor M. Liplianin 	/* set DiSEqC mode, modulation active during 33 pulses,
71709ea33e5SIgor M. Liplianin 	set DiSEqC message length */
71809ea33e5SIgor M. Liplianin 	data |= ((d->msg_len - 1) << 3) | 0x07;
71909ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xa1, data);
72009ea33e5SIgor M. Liplianin 
72109ea33e5SIgor M. Liplianin 	/* wait up to 150ms for DiSEqC transmission to complete */
72209ea33e5SIgor M. Liplianin 	for (i = 0; i < 15; i++) {
72309ea33e5SIgor M. Liplianin 		data = ds3000_readreg(state, 0xa1);
72409ea33e5SIgor M. Liplianin 		if ((data & 0x40) == 0)
72509ea33e5SIgor M. Liplianin 			break;
72609ea33e5SIgor M. Liplianin 		msleep(10);
72709ea33e5SIgor M. Liplianin 	}
72809ea33e5SIgor M. Liplianin 
72909ea33e5SIgor M. Liplianin 	/* DiSEqC timeout after 150ms */
73009ea33e5SIgor M. Liplianin 	if (i == 15) {
73109ea33e5SIgor M. Liplianin 		data = ds3000_readreg(state, 0xa1);
73209ea33e5SIgor M. Liplianin 		data &= ~0x80;
73309ea33e5SIgor M. Liplianin 		data |= 0x40;
73409ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xa1, data);
73509ea33e5SIgor M. Liplianin 
73609ea33e5SIgor M. Liplianin 		data = ds3000_readreg(state, 0xa2);
73709ea33e5SIgor M. Liplianin 		data &= ~0xc0;
73809ea33e5SIgor M. Liplianin 		data |= 0x80;
73909ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xa2, data);
74009ea33e5SIgor M. Liplianin 
74109ea33e5SIgor M. Liplianin 		return 1;
74209ea33e5SIgor M. Liplianin 	}
74309ea33e5SIgor M. Liplianin 
74409ea33e5SIgor M. Liplianin 	data = ds3000_readreg(state, 0xa2);
74509ea33e5SIgor M. Liplianin 	data &= ~0xc0;
74609ea33e5SIgor M. Liplianin 	data |= 0x80;
74709ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xa2, data);
74809ea33e5SIgor M. Liplianin 
74909ea33e5SIgor M. Liplianin 	return 0;
75009ea33e5SIgor M. Liplianin }
75109ea33e5SIgor M. Liplianin 
75209ea33e5SIgor M. Liplianin /* Send DiSEqC burst */
75309ea33e5SIgor M. Liplianin static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
75409ea33e5SIgor M. Liplianin 					fe_sec_mini_cmd_t burst)
75509ea33e5SIgor M. Liplianin {
75609ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
75709ea33e5SIgor M. Liplianin 	int i;
75809ea33e5SIgor M. Liplianin 	u8 data;
75909ea33e5SIgor M. Liplianin 
76009ea33e5SIgor M. Liplianin 	dprintk("%s()\n", __func__);
76109ea33e5SIgor M. Liplianin 
76209ea33e5SIgor M. Liplianin 	data = ds3000_readreg(state, 0xa2);
76309ea33e5SIgor M. Liplianin 	data &= ~0xc0;
76409ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xa2, data);
76509ea33e5SIgor M. Liplianin 
76609ea33e5SIgor M. Liplianin 	/* DiSEqC burst */
76709ea33e5SIgor M. Liplianin 	if (burst == SEC_MINI_A)
76809ea33e5SIgor M. Liplianin 		/* Unmodulated tone burst */
76909ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xa1, 0x02);
77009ea33e5SIgor M. Liplianin 	else if (burst == SEC_MINI_B)
77109ea33e5SIgor M. Liplianin 		/* Modulated tone burst */
77209ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xa1, 0x01);
77309ea33e5SIgor M. Liplianin 	else
77409ea33e5SIgor M. Liplianin 		return -EINVAL;
77509ea33e5SIgor M. Liplianin 
77609ea33e5SIgor M. Liplianin 	msleep(13);
77709ea33e5SIgor M. Liplianin 	for (i = 0; i < 5; i++) {
77809ea33e5SIgor M. Liplianin 		data = ds3000_readreg(state, 0xa1);
77909ea33e5SIgor M. Liplianin 		if ((data & 0x40) == 0)
78009ea33e5SIgor M. Liplianin 			break;
78109ea33e5SIgor M. Liplianin 		msleep(1);
78209ea33e5SIgor M. Liplianin 	}
78309ea33e5SIgor M. Liplianin 
78409ea33e5SIgor M. Liplianin 	if (i == 5) {
78509ea33e5SIgor M. Liplianin 		data = ds3000_readreg(state, 0xa1);
78609ea33e5SIgor M. Liplianin 		data &= ~0x80;
78709ea33e5SIgor M. Liplianin 		data |= 0x40;
78809ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xa1, data);
78909ea33e5SIgor M. Liplianin 
79009ea33e5SIgor M. Liplianin 		data = ds3000_readreg(state, 0xa2);
79109ea33e5SIgor M. Liplianin 		data &= ~0xc0;
79209ea33e5SIgor M. Liplianin 		data |= 0x80;
79309ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xa2, data);
79409ea33e5SIgor M. Liplianin 
79509ea33e5SIgor M. Liplianin 		return 1;
79609ea33e5SIgor M. Liplianin 	}
79709ea33e5SIgor M. Liplianin 
79809ea33e5SIgor M. Liplianin 	data = ds3000_readreg(state, 0xa2);
79909ea33e5SIgor M. Liplianin 	data &= ~0xc0;
80009ea33e5SIgor M. Liplianin 	data |= 0x80;
80109ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xa2, data);
80209ea33e5SIgor M. Liplianin 
80309ea33e5SIgor M. Liplianin 	return 0;
80409ea33e5SIgor M. Liplianin }
80509ea33e5SIgor M. Liplianin 
80609ea33e5SIgor M. Liplianin static void ds3000_release(struct dvb_frontend *fe)
80709ea33e5SIgor M. Liplianin {
80809ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
80909ea33e5SIgor M. Liplianin 	dprintk("%s\n", __func__);
81009ea33e5SIgor M. Liplianin 	kfree(state);
81109ea33e5SIgor M. Liplianin }
81209ea33e5SIgor M. Liplianin 
81309ea33e5SIgor M. Liplianin static struct dvb_frontend_ops ds3000_ops;
81409ea33e5SIgor M. Liplianin 
81509ea33e5SIgor M. Liplianin struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
81609ea33e5SIgor M. Liplianin 				    struct i2c_adapter *i2c)
81709ea33e5SIgor M. Liplianin {
81809ea33e5SIgor M. Liplianin 	struct ds3000_state *state = NULL;
81909ea33e5SIgor M. Liplianin 	int ret;
82009ea33e5SIgor M. Liplianin 
82109ea33e5SIgor M. Liplianin 	dprintk("%s\n", __func__);
82209ea33e5SIgor M. Liplianin 
82309ea33e5SIgor M. Liplianin 	/* allocate memory for the internal state */
8242ef17c9fSJulia Lawall 	state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
82509ea33e5SIgor M. Liplianin 	if (state == NULL) {
82609ea33e5SIgor M. Liplianin 		printk(KERN_ERR "Unable to kmalloc\n");
82709ea33e5SIgor M. Liplianin 		goto error2;
82809ea33e5SIgor M. Liplianin 	}
82909ea33e5SIgor M. Liplianin 
83009ea33e5SIgor M. Liplianin 	state->config = config;
83109ea33e5SIgor M. Liplianin 	state->i2c = i2c;
83209ea33e5SIgor M. Liplianin 	state->prevUCBS2 = 0;
83309ea33e5SIgor M. Liplianin 
83409ea33e5SIgor M. Liplianin 	/* check if the demod is present */
83509ea33e5SIgor M. Liplianin 	ret = ds3000_readreg(state, 0x00) & 0xfe;
83609ea33e5SIgor M. Liplianin 	if (ret != 0xe0) {
83709ea33e5SIgor M. Liplianin 		printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
83809ea33e5SIgor M. Liplianin 		goto error3;
83909ea33e5SIgor M. Liplianin 	}
84009ea33e5SIgor M. Liplianin 
84109ea33e5SIgor M. Liplianin 	printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
84209ea33e5SIgor M. Liplianin 			ds3000_readreg(state, 0x02),
84309ea33e5SIgor M. Liplianin 			ds3000_readreg(state, 0x01));
84409ea33e5SIgor M. Liplianin 
84509ea33e5SIgor M. Liplianin 	memcpy(&state->frontend.ops, &ds3000_ops,
84609ea33e5SIgor M. Liplianin 			sizeof(struct dvb_frontend_ops));
84709ea33e5SIgor M. Liplianin 	state->frontend.demodulator_priv = state;
84809ea33e5SIgor M. Liplianin 	return &state->frontend;
84909ea33e5SIgor M. Liplianin 
85009ea33e5SIgor M. Liplianin error3:
85109ea33e5SIgor M. Liplianin 	kfree(state);
85209ea33e5SIgor M. Liplianin error2:
85309ea33e5SIgor M. Liplianin 	return NULL;
85409ea33e5SIgor M. Liplianin }
85509ea33e5SIgor M. Liplianin EXPORT_SYMBOL(ds3000_attach);
85609ea33e5SIgor M. Liplianin 
857a5bf834bSIgor M. Liplianin static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
858a5bf834bSIgor M. Liplianin 					s32 carrier_offset_khz)
859a5bf834bSIgor M. Liplianin {
860a5bf834bSIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
861a5bf834bSIgor M. Liplianin 	s32 tmp;
862a5bf834bSIgor M. Liplianin 
863a5bf834bSIgor M. Liplianin 	tmp = carrier_offset_khz;
864a5bf834bSIgor M. Liplianin 	tmp *= 65536;
865a5bf834bSIgor M. Liplianin 	tmp = (2 * tmp + DS3000_SAMPLE_RATE) / (2 * DS3000_SAMPLE_RATE);
866a5bf834bSIgor M. Liplianin 
867a5bf834bSIgor M. Liplianin 	if (tmp < 0)
868a5bf834bSIgor M. Liplianin 		tmp += 65536;
869a5bf834bSIgor M. Liplianin 
870a5bf834bSIgor M. Liplianin 	ds3000_writereg(state, 0x5f, tmp >> 8);
871a5bf834bSIgor M. Liplianin 	ds3000_writereg(state, 0x5e, tmp & 0xff);
872a5bf834bSIgor M. Liplianin 
873a5bf834bSIgor M. Liplianin 	return 0;
874a5bf834bSIgor M. Liplianin }
875a5bf834bSIgor M. Liplianin 
8769fe33018SMauro Carvalho Chehab static int ds3000_set_frontend(struct dvb_frontend *fe)
87709ea33e5SIgor M. Liplianin {
87809ea33e5SIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
87909ea33e5SIgor M. Liplianin 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
88009ea33e5SIgor M. Liplianin 
88118a73f36SIgor M. Liplianin 	int i;
882dcc8a122SIgor M. Liplianin 	fe_status_t status;
883a5bf834bSIgor M. Liplianin 	s32 offset_khz;
884*c1965eaeSKonstantin Dimitrov 	u32 frequency;
885*c1965eaeSKonstantin Dimitrov 	u16 value;
88609ea33e5SIgor M. Liplianin 
88709ea33e5SIgor M. Liplianin 	dprintk("%s() ", __func__);
88809ea33e5SIgor M. Liplianin 
8890cb73639SIgor M. Liplianin 	if (state->config->set_ts_params)
8900cb73639SIgor M. Liplianin 		state->config->set_ts_params(fe, 0);
89109ea33e5SIgor M. Liplianin 	/* Tune */
892*c1965eaeSKonstantin Dimitrov 	if (fe->ops.tuner_ops.set_params)
893*c1965eaeSKonstantin Dimitrov 		fe->ops.tuner_ops.set_params(fe);
894a5bf834bSIgor M. Liplianin 
89509ea33e5SIgor M. Liplianin 	/* ds3000 global reset */
89609ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x07, 0x80);
89709ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x07, 0x00);
89809ea33e5SIgor M. Liplianin 	/* ds3000 build-in uC reset */
89909ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xb2, 0x01);
90009ea33e5SIgor M. Liplianin 	/* ds3000 software reset */
90109ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x00, 0x01);
90209ea33e5SIgor M. Liplianin 
90309ea33e5SIgor M. Liplianin 	switch (c->delivery_system) {
90409ea33e5SIgor M. Liplianin 	case SYS_DVBS:
90509ea33e5SIgor M. Liplianin 		/* initialise the demod in DVB-S mode */
90609ea33e5SIgor M. Liplianin 		for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
90709ea33e5SIgor M. Liplianin 			ds3000_writereg(state,
90809ea33e5SIgor M. Liplianin 				ds3000_dvbs_init_tab[i],
90909ea33e5SIgor M. Liplianin 				ds3000_dvbs_init_tab[i + 1]);
91009ea33e5SIgor M. Liplianin 		value = ds3000_readreg(state, 0xfe);
91109ea33e5SIgor M. Liplianin 		value &= 0xc0;
91209ea33e5SIgor M. Liplianin 		value |= 0x1b;
91309ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xfe, value);
91409ea33e5SIgor M. Liplianin 		break;
91509ea33e5SIgor M. Liplianin 	case SYS_DVBS2:
91609ea33e5SIgor M. Liplianin 		/* initialise the demod in DVB-S2 mode */
91709ea33e5SIgor M. Liplianin 		for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
91809ea33e5SIgor M. Liplianin 			ds3000_writereg(state,
91909ea33e5SIgor M. Liplianin 				ds3000_dvbs2_init_tab[i],
92009ea33e5SIgor M. Liplianin 				ds3000_dvbs2_init_tab[i + 1]);
9217b134e85SIgor M. Liplianin 		if (c->symbol_rate >= 30000000)
9227b134e85SIgor M. Liplianin 			ds3000_writereg(state, 0xfe, 0x54);
9237b134e85SIgor M. Liplianin 		else
9242a66bf37SIgor M. Liplianin 			ds3000_writereg(state, 0xfe, 0x98);
92509ea33e5SIgor M. Liplianin 		break;
92609ea33e5SIgor M. Liplianin 	default:
92709ea33e5SIgor M. Liplianin 		return 1;
92809ea33e5SIgor M. Liplianin 	}
92909ea33e5SIgor M. Liplianin 
93009ea33e5SIgor M. Liplianin 	/* enable 27MHz clock output */
93109ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x29, 0x80);
93209ea33e5SIgor M. Liplianin 	/* enable ac coupling */
93309ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x25, 0x8a);
93409ea33e5SIgor M. Liplianin 
93509ea33e5SIgor M. Liplianin 	/* enhance symbol rate performance */
936cb8f74daSIgor M. Liplianin 	if ((c->symbol_rate / 1000) <= 5000) {
937cb8f74daSIgor M. Liplianin 		value = 29777 / (c->symbol_rate / 1000) + 1;
93809ea33e5SIgor M. Liplianin 		if (value % 2 != 0)
93909ea33e5SIgor M. Liplianin 			value++;
94009ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc3, 0x0d);
94109ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc8, value);
94209ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc4, 0x10);
94309ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc7, 0x0e);
944cb8f74daSIgor M. Liplianin 	} else if ((c->symbol_rate / 1000) <= 10000) {
945cb8f74daSIgor M. Liplianin 		value = 92166 / (c->symbol_rate / 1000) + 1;
94609ea33e5SIgor M. Liplianin 		if (value % 2 != 0)
94709ea33e5SIgor M. Liplianin 			value++;
94809ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc3, 0x07);
94909ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc8, value);
95009ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc4, 0x09);
95109ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc7, 0x12);
952cb8f74daSIgor M. Liplianin 	} else if ((c->symbol_rate / 1000) <= 20000) {
953cb8f74daSIgor M. Liplianin 		value = 64516 / (c->symbol_rate / 1000) + 1;
95409ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc3, value);
95509ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc8, 0x0e);
95609ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc4, 0x07);
95709ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc7, 0x18);
95809ea33e5SIgor M. Liplianin 	} else {
959cb8f74daSIgor M. Liplianin 		value = 129032 / (c->symbol_rate / 1000) + 1;
96009ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc3, value);
96109ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc8, 0x0a);
96209ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc4, 0x05);
96309ea33e5SIgor M. Liplianin 		ds3000_writereg(state, 0xc7, 0x24);
96409ea33e5SIgor M. Liplianin 	}
96509ea33e5SIgor M. Liplianin 
96609ea33e5SIgor M. Liplianin 	/* normalized symbol rate rounded to the closest integer */
967cb8f74daSIgor M. Liplianin 	value = (((c->symbol_rate / 1000) << 16) +
96809ea33e5SIgor M. Liplianin 			(DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
96909ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x61, value & 0x00ff);
97009ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
97109ea33e5SIgor M. Liplianin 
97209ea33e5SIgor M. Liplianin 	/* co-channel interference cancellation disabled */
97309ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x56, 0x00);
97409ea33e5SIgor M. Liplianin 
97509ea33e5SIgor M. Liplianin 	/* equalizer disabled */
97609ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x76, 0x00);
97709ea33e5SIgor M. Liplianin 
97809ea33e5SIgor M. Liplianin 	/*ds3000_writereg(state, 0x08, 0x03);
97909ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xfd, 0x22);
98009ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x08, 0x07);
98109ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xfd, 0x42);
98209ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x08, 0x07);*/
98309ea33e5SIgor M. Liplianin 
984d2ffc447SIgor M. Liplianin 	if (state->config->ci_mode) {
985d2ffc447SIgor M. Liplianin 		switch (c->delivery_system) {
986d2ffc447SIgor M. Liplianin 		case SYS_DVBS:
987d2ffc447SIgor M. Liplianin 		default:
988d2ffc447SIgor M. Liplianin 			ds3000_writereg(state, 0xfd, 0x80);
989d2ffc447SIgor M. Liplianin 		break;
990d2ffc447SIgor M. Liplianin 		case SYS_DVBS2:
991d2ffc447SIgor M. Liplianin 			ds3000_writereg(state, 0xfd, 0x01);
992d2ffc447SIgor M. Liplianin 			break;
993d2ffc447SIgor M. Liplianin 		}
994d2ffc447SIgor M. Liplianin 	}
995d2ffc447SIgor M. Liplianin 
99609ea33e5SIgor M. Liplianin 	/* ds3000 out of software reset */
99709ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0x00, 0x00);
99809ea33e5SIgor M. Liplianin 	/* start ds3000 build-in uC */
99909ea33e5SIgor M. Liplianin 	ds3000_writereg(state, 0xb2, 0x00);
100009ea33e5SIgor M. Liplianin 
1001*c1965eaeSKonstantin Dimitrov 	if (fe->ops.tuner_ops.get_frequency) {
1002*c1965eaeSKonstantin Dimitrov 		fe->ops.tuner_ops.get_frequency(fe, &frequency);
1003*c1965eaeSKonstantin Dimitrov 		offset_khz = frequency - c->frequency;
1004a5bf834bSIgor M. Liplianin 		ds3000_set_carrier_offset(fe, offset_khz);
1005*c1965eaeSKonstantin Dimitrov 	}
100609ea33e5SIgor M. Liplianin 
100709ea33e5SIgor M. Liplianin 	for (i = 0; i < 30 ; i++) {
100818a73f36SIgor M. Liplianin 		ds3000_read_status(fe, &status);
10093a9888f9SDan Carpenter 		if (status & FE_HAS_LOCK)
101018a73f36SIgor M. Liplianin 			break;
101118a73f36SIgor M. Liplianin 
101218a73f36SIgor M. Liplianin 		msleep(10);
101309ea33e5SIgor M. Liplianin 	}
101409ea33e5SIgor M. Liplianin 
101518a73f36SIgor M. Liplianin 	return 0;
101609ea33e5SIgor M. Liplianin }
101709ea33e5SIgor M. Liplianin 
1018dcc8a122SIgor M. Liplianin static int ds3000_tune(struct dvb_frontend *fe,
10197e072221SMauro Carvalho Chehab 			bool re_tune,
1020738e8ff9SIgor M. Liplianin 			unsigned int mode_flags,
1021738e8ff9SIgor M. Liplianin 			unsigned int *delay,
1022738e8ff9SIgor M. Liplianin 			fe_status_t *status)
1023dcc8a122SIgor M. Liplianin {
10247e072221SMauro Carvalho Chehab 	if (re_tune) {
10259fe33018SMauro Carvalho Chehab 		int ret = ds3000_set_frontend(fe);
1026738e8ff9SIgor M. Liplianin 		if (ret)
1027738e8ff9SIgor M. Liplianin 			return ret;
1028738e8ff9SIgor M. Liplianin 	}
1029738e8ff9SIgor M. Liplianin 
1030738e8ff9SIgor M. Liplianin 	*delay = HZ / 5;
1031738e8ff9SIgor M. Liplianin 
1032738e8ff9SIgor M. Liplianin 	return ds3000_read_status(fe, status);
1033dcc8a122SIgor M. Liplianin }
1034dcc8a122SIgor M. Liplianin 
103509ea33e5SIgor M. Liplianin static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
103609ea33e5SIgor M. Liplianin {
103709ea33e5SIgor M. Liplianin 	dprintk("%s()\n", __func__);
1038dcc8a122SIgor M. Liplianin 	return DVBFE_ALGO_HW;
103909ea33e5SIgor M. Liplianin }
104009ea33e5SIgor M. Liplianin 
104109ea33e5SIgor M. Liplianin /*
104209ea33e5SIgor M. Liplianin  * Initialise or wake up device
104309ea33e5SIgor M. Liplianin  *
104409ea33e5SIgor M. Liplianin  * Power config will reset and load initial firmware if required
104509ea33e5SIgor M. Liplianin  */
104609ea33e5SIgor M. Liplianin static int ds3000_initfe(struct dvb_frontend *fe)
104709ea33e5SIgor M. Liplianin {
1048a0ea298dSIgor M. Liplianin 	struct ds3000_state *state = fe->demodulator_priv;
1049a0ea298dSIgor M. Liplianin 	int ret;
1050a0ea298dSIgor M. Liplianin 
105109ea33e5SIgor M. Liplianin 	dprintk("%s()\n", __func__);
1052a0ea298dSIgor M. Liplianin 	/* hard reset */
1053a0ea298dSIgor M. Liplianin 	ds3000_writereg(state, 0x08, 0x01 | ds3000_readreg(state, 0x08));
1054a0ea298dSIgor M. Liplianin 	msleep(1);
1055a0ea298dSIgor M. Liplianin 
1056b9bf2eafSIgor M. Liplianin 	/* Load the firmware if required */
1057b9bf2eafSIgor M. Liplianin 	ret = ds3000_firmware_ondemand(fe);
1058b9bf2eafSIgor M. Liplianin 	if (ret != 0) {
1059b9bf2eafSIgor M. Liplianin 		printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
1060b9bf2eafSIgor M. Liplianin 		return ret;
1061b9bf2eafSIgor M. Liplianin 	}
1062a0ea298dSIgor M. Liplianin 
106309ea33e5SIgor M. Liplianin 	return 0;
106409ea33e5SIgor M. Liplianin }
106509ea33e5SIgor M. Liplianin 
106609ea33e5SIgor M. Liplianin static struct dvb_frontend_ops ds3000_ops = {
10679fe33018SMauro Carvalho Chehab 	.delsys = { SYS_DVBS, SYS_DVBS2 },
106809ea33e5SIgor M. Liplianin 	.info = {
1069*c1965eaeSKonstantin Dimitrov 		.name = "Montage Technology DS3000",
107009ea33e5SIgor M. Liplianin 		.frequency_min = 950000,
107109ea33e5SIgor M. Liplianin 		.frequency_max = 2150000,
107209ea33e5SIgor M. Liplianin 		.frequency_stepsize = 1011, /* kHz for QPSK frontends */
107309ea33e5SIgor M. Liplianin 		.frequency_tolerance = 5000,
107409ea33e5SIgor M. Liplianin 		.symbol_rate_min = 1000000,
107509ea33e5SIgor M. Liplianin 		.symbol_rate_max = 45000000,
107609ea33e5SIgor M. Liplianin 		.caps = FE_CAN_INVERSION_AUTO |
107709ea33e5SIgor M. Liplianin 			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
107809ea33e5SIgor M. Liplianin 			FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
107909ea33e5SIgor M. Liplianin 			FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
108009ea33e5SIgor M. Liplianin 			FE_CAN_2G_MODULATION |
108109ea33e5SIgor M. Liplianin 			FE_CAN_QPSK | FE_CAN_RECOVER
108209ea33e5SIgor M. Liplianin 	},
108309ea33e5SIgor M. Liplianin 
108409ea33e5SIgor M. Liplianin 	.release = ds3000_release,
108509ea33e5SIgor M. Liplianin 
108609ea33e5SIgor M. Liplianin 	.init = ds3000_initfe,
1087*c1965eaeSKonstantin Dimitrov 	.i2c_gate_ctrl = ds3000_i2c_gate_ctrl,
108809ea33e5SIgor M. Liplianin 	.read_status = ds3000_read_status,
108909ea33e5SIgor M. Liplianin 	.read_ber = ds3000_read_ber,
109009ea33e5SIgor M. Liplianin 	.read_snr = ds3000_read_snr,
109109ea33e5SIgor M. Liplianin 	.read_ucblocks = ds3000_read_ucblocks,
1092d2ffc447SIgor M. Liplianin 	.set_voltage = ds3000_set_voltage,
109309ea33e5SIgor M. Liplianin 	.set_tone = ds3000_set_tone,
109409ea33e5SIgor M. Liplianin 	.diseqc_send_master_cmd = ds3000_send_diseqc_msg,
109509ea33e5SIgor M. Liplianin 	.diseqc_send_burst = ds3000_diseqc_send_burst,
109609ea33e5SIgor M. Liplianin 	.get_frontend_algo = ds3000_get_algo,
109709ea33e5SIgor M. Liplianin 
10989fe33018SMauro Carvalho Chehab 	.set_frontend = ds3000_set_frontend,
1099dcc8a122SIgor M. Liplianin 	.tune = ds3000_tune,
110009ea33e5SIgor M. Liplianin };
110109ea33e5SIgor M. Liplianin 
110209ea33e5SIgor M. Liplianin module_param(debug, int, 0644);
110309ea33e5SIgor M. Liplianin MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
110409ea33e5SIgor M. Liplianin 
110509ea33e5SIgor M. Liplianin MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
1106*c1965eaeSKonstantin Dimitrov 			"DS3000 hardware");
1107*c1965eaeSKonstantin Dimitrov MODULE_AUTHOR("Konstantin Dimitrov <kosio.dimitrov@gmail.com>");
110809ea33e5SIgor M. Liplianin MODULE_LICENSE("GPL");
1109feadd7d3SRémi Cardona MODULE_FIRMWARE(DS3000_DEFAULT_FIRMWARE);
1110