1*74ba9207SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
225aee3deSMauro Carvalho Chehab /*
325aee3deSMauro Carvalho Chehab Mantis VP-1033 driver
425aee3deSMauro Carvalho Chehab
525aee3deSMauro Carvalho Chehab Copyright (C) Manu Abraham (abraham.manu@gmail.com)
625aee3deSMauro Carvalho Chehab
725aee3deSMauro Carvalho Chehab */
825aee3deSMauro Carvalho Chehab
925aee3deSMauro Carvalho Chehab #include <linux/signal.h>
1025aee3deSMauro Carvalho Chehab #include <linux/sched.h>
1125aee3deSMauro Carvalho Chehab #include <linux/interrupt.h>
1225aee3deSMauro Carvalho Chehab
13fada1935SMauro Carvalho Chehab #include <media/dmxdev.h>
14fada1935SMauro Carvalho Chehab #include <media/dvbdev.h>
15fada1935SMauro Carvalho Chehab #include <media/dvb_demux.h>
16fada1935SMauro Carvalho Chehab #include <media/dvb_frontend.h>
17fada1935SMauro Carvalho Chehab #include <media/dvb_net.h>
1825aee3deSMauro Carvalho Chehab
1925aee3deSMauro Carvalho Chehab #include "stv0299.h"
2025aee3deSMauro Carvalho Chehab #include "mantis_common.h"
2125aee3deSMauro Carvalho Chehab #include "mantis_ioc.h"
2225aee3deSMauro Carvalho Chehab #include "mantis_dvb.h"
2325aee3deSMauro Carvalho Chehab #include "mantis_vp1033.h"
2425aee3deSMauro Carvalho Chehab #include "mantis_reg.h"
2525aee3deSMauro Carvalho Chehab
26967a3783SHans Verkuil static u8 lgtdqcs001f_inittab[] = {
2725aee3deSMauro Carvalho Chehab 0x01, 0x15,
2825aee3deSMauro Carvalho Chehab 0x02, 0x30,
2925aee3deSMauro Carvalho Chehab 0x03, 0x00,
3025aee3deSMauro Carvalho Chehab 0x04, 0x2a,
3125aee3deSMauro Carvalho Chehab 0x05, 0x85,
3225aee3deSMauro Carvalho Chehab 0x06, 0x02,
3325aee3deSMauro Carvalho Chehab 0x07, 0x00,
3425aee3deSMauro Carvalho Chehab 0x08, 0x00,
3525aee3deSMauro Carvalho Chehab 0x0c, 0x01,
3625aee3deSMauro Carvalho Chehab 0x0d, 0x81,
3725aee3deSMauro Carvalho Chehab 0x0e, 0x44,
3825aee3deSMauro Carvalho Chehab 0x0f, 0x94,
3925aee3deSMauro Carvalho Chehab 0x10, 0x3c,
4025aee3deSMauro Carvalho Chehab 0x11, 0x84,
4125aee3deSMauro Carvalho Chehab 0x12, 0xb9,
4225aee3deSMauro Carvalho Chehab 0x13, 0xb5,
4325aee3deSMauro Carvalho Chehab 0x14, 0x4f,
4425aee3deSMauro Carvalho Chehab 0x15, 0xc9,
4525aee3deSMauro Carvalho Chehab 0x16, 0x80,
4625aee3deSMauro Carvalho Chehab 0x17, 0x36,
4725aee3deSMauro Carvalho Chehab 0x18, 0xfb,
4825aee3deSMauro Carvalho Chehab 0x19, 0xcf,
4925aee3deSMauro Carvalho Chehab 0x1a, 0xbc,
5025aee3deSMauro Carvalho Chehab 0x1c, 0x2b,
5125aee3deSMauro Carvalho Chehab 0x1d, 0x27,
5225aee3deSMauro Carvalho Chehab 0x1e, 0x00,
5325aee3deSMauro Carvalho Chehab 0x1f, 0x0b,
5425aee3deSMauro Carvalho Chehab 0x20, 0xa1,
5525aee3deSMauro Carvalho Chehab 0x21, 0x60,
5625aee3deSMauro Carvalho Chehab 0x22, 0x00,
5725aee3deSMauro Carvalho Chehab 0x23, 0x00,
5825aee3deSMauro Carvalho Chehab 0x28, 0x00,
5925aee3deSMauro Carvalho Chehab 0x29, 0x28,
6025aee3deSMauro Carvalho Chehab 0x2a, 0x14,
6125aee3deSMauro Carvalho Chehab 0x2b, 0x0f,
6225aee3deSMauro Carvalho Chehab 0x2c, 0x09,
6325aee3deSMauro Carvalho Chehab 0x2d, 0x05,
6425aee3deSMauro Carvalho Chehab 0x31, 0x1f,
6525aee3deSMauro Carvalho Chehab 0x32, 0x19,
6625aee3deSMauro Carvalho Chehab 0x33, 0xfc,
6725aee3deSMauro Carvalho Chehab 0x34, 0x13,
6825aee3deSMauro Carvalho Chehab 0xff, 0xff,
6925aee3deSMauro Carvalho Chehab };
7025aee3deSMauro Carvalho Chehab
7125aee3deSMauro Carvalho Chehab #define MANTIS_MODEL_NAME "VP-1033"
7225aee3deSMauro Carvalho Chehab #define MANTIS_DEV_TYPE "DVB-S/DSS"
7325aee3deSMauro Carvalho Chehab
lgtdqcs001f_tuner_set(struct dvb_frontend * fe)746860f9caSMauro Carvalho Chehab static int lgtdqcs001f_tuner_set(struct dvb_frontend *fe)
7525aee3deSMauro Carvalho Chehab {
7625aee3deSMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache;
7725aee3deSMauro Carvalho Chehab struct mantis_pci *mantis = fe->dvb->priv;
7825aee3deSMauro Carvalho Chehab struct i2c_adapter *adapter = &mantis->adapter;
7925aee3deSMauro Carvalho Chehab
8025aee3deSMauro Carvalho Chehab u8 buf[4];
8125aee3deSMauro Carvalho Chehab u32 div;
8225aee3deSMauro Carvalho Chehab
8325aee3deSMauro Carvalho Chehab
8425aee3deSMauro Carvalho Chehab struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)};
8525aee3deSMauro Carvalho Chehab
8625aee3deSMauro Carvalho Chehab div = p->frequency / 250;
8725aee3deSMauro Carvalho Chehab
8825aee3deSMauro Carvalho Chehab buf[0] = (div >> 8) & 0x7f;
8925aee3deSMauro Carvalho Chehab buf[1] = div & 0xff;
9025aee3deSMauro Carvalho Chehab buf[2] = 0x83;
9125aee3deSMauro Carvalho Chehab buf[3] = 0xc0;
9225aee3deSMauro Carvalho Chehab
9325aee3deSMauro Carvalho Chehab if (p->frequency < 1531000)
9425aee3deSMauro Carvalho Chehab buf[3] |= 0x04;
9525aee3deSMauro Carvalho Chehab else
9625aee3deSMauro Carvalho Chehab buf[3] &= ~0x04;
9725aee3deSMauro Carvalho Chehab if (i2c_transfer(adapter, &msg, 1) < 0) {
9825aee3deSMauro Carvalho Chehab dprintk(MANTIS_ERROR, 1, "Write: I2C Transfer failed");
9925aee3deSMauro Carvalho Chehab return -EIO;
10025aee3deSMauro Carvalho Chehab }
10125aee3deSMauro Carvalho Chehab msleep_interruptible(100);
10225aee3deSMauro Carvalho Chehab
10325aee3deSMauro Carvalho Chehab return 0;
10425aee3deSMauro Carvalho Chehab }
10525aee3deSMauro Carvalho Chehab
lgtdqcs001f_set_symbol_rate(struct dvb_frontend * fe,u32 srate,u32 ratio)1066860f9caSMauro Carvalho Chehab static int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe,
10725aee3deSMauro Carvalho Chehab u32 srate, u32 ratio)
10825aee3deSMauro Carvalho Chehab {
10925aee3deSMauro Carvalho Chehab u8 aclk = 0;
11025aee3deSMauro Carvalho Chehab u8 bclk = 0;
11125aee3deSMauro Carvalho Chehab
11225aee3deSMauro Carvalho Chehab if (srate < 1500000) {
11325aee3deSMauro Carvalho Chehab aclk = 0xb7;
11425aee3deSMauro Carvalho Chehab bclk = 0x47;
11525aee3deSMauro Carvalho Chehab } else if (srate < 3000000) {
11625aee3deSMauro Carvalho Chehab aclk = 0xb7;
11725aee3deSMauro Carvalho Chehab bclk = 0x4b;
11825aee3deSMauro Carvalho Chehab } else if (srate < 7000000) {
11925aee3deSMauro Carvalho Chehab aclk = 0xb7;
12025aee3deSMauro Carvalho Chehab bclk = 0x4f;
12125aee3deSMauro Carvalho Chehab } else if (srate < 14000000) {
12225aee3deSMauro Carvalho Chehab aclk = 0xb7;
12325aee3deSMauro Carvalho Chehab bclk = 0x53;
12425aee3deSMauro Carvalho Chehab } else if (srate < 30000000) {
12525aee3deSMauro Carvalho Chehab aclk = 0xb6;
12625aee3deSMauro Carvalho Chehab bclk = 0x53;
12725aee3deSMauro Carvalho Chehab } else if (srate < 45000000) {
12825aee3deSMauro Carvalho Chehab aclk = 0xb4;
12925aee3deSMauro Carvalho Chehab bclk = 0x51;
13025aee3deSMauro Carvalho Chehab }
13125aee3deSMauro Carvalho Chehab stv0299_writereg(fe, 0x13, aclk);
13225aee3deSMauro Carvalho Chehab stv0299_writereg(fe, 0x14, bclk);
13325aee3deSMauro Carvalho Chehab
13425aee3deSMauro Carvalho Chehab stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
13525aee3deSMauro Carvalho Chehab stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
13625aee3deSMauro Carvalho Chehab stv0299_writereg(fe, 0x21, ratio & 0xf0);
13725aee3deSMauro Carvalho Chehab
13825aee3deSMauro Carvalho Chehab return 0;
13925aee3deSMauro Carvalho Chehab }
14025aee3deSMauro Carvalho Chehab
141967a3783SHans Verkuil static struct stv0299_config lgtdqcs001f_config = {
14225aee3deSMauro Carvalho Chehab .demod_address = 0x68,
14325aee3deSMauro Carvalho Chehab .inittab = lgtdqcs001f_inittab,
14425aee3deSMauro Carvalho Chehab .mclk = 88000000UL,
14525aee3deSMauro Carvalho Chehab .invert = 0,
14625aee3deSMauro Carvalho Chehab .skip_reinit = 0,
14725aee3deSMauro Carvalho Chehab .volt13_op0_op1 = STV0299_VOLT13_OP0,
14825aee3deSMauro Carvalho Chehab .min_delay_ms = 100,
14925aee3deSMauro Carvalho Chehab .set_symbol_rate = lgtdqcs001f_set_symbol_rate,
15025aee3deSMauro Carvalho Chehab };
15125aee3deSMauro Carvalho Chehab
vp1033_frontend_init(struct mantis_pci * mantis,struct dvb_frontend * fe)15225aee3deSMauro Carvalho Chehab static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
15325aee3deSMauro Carvalho Chehab {
15425aee3deSMauro Carvalho Chehab struct i2c_adapter *adapter = &mantis->adapter;
15525aee3deSMauro Carvalho Chehab
15625aee3deSMauro Carvalho Chehab int err = 0;
15725aee3deSMauro Carvalho Chehab
15825aee3deSMauro Carvalho Chehab err = mantis_frontend_power(mantis, POWER_ON);
15925aee3deSMauro Carvalho Chehab if (err == 0) {
16025aee3deSMauro Carvalho Chehab mantis_frontend_soft_reset(mantis);
16125aee3deSMauro Carvalho Chehab msleep(250);
16225aee3deSMauro Carvalho Chehab
16325aee3deSMauro Carvalho Chehab dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
16425aee3deSMauro Carvalho Chehab fe = dvb_attach(stv0299_attach, &lgtdqcs001f_config, adapter);
16525aee3deSMauro Carvalho Chehab
16625aee3deSMauro Carvalho Chehab if (fe) {
16725aee3deSMauro Carvalho Chehab fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;
16825aee3deSMauro Carvalho Chehab dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x",
16925aee3deSMauro Carvalho Chehab lgtdqcs001f_config.demod_address);
17025aee3deSMauro Carvalho Chehab
17125aee3deSMauro Carvalho Chehab dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success");
17225aee3deSMauro Carvalho Chehab } else {
17325aee3deSMauro Carvalho Chehab return -1;
17425aee3deSMauro Carvalho Chehab }
17525aee3deSMauro Carvalho Chehab } else {
17625aee3deSMauro Carvalho Chehab dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
17725aee3deSMauro Carvalho Chehab adapter->name,
17825aee3deSMauro Carvalho Chehab err);
17925aee3deSMauro Carvalho Chehab
18025aee3deSMauro Carvalho Chehab return -EIO;
18125aee3deSMauro Carvalho Chehab }
18225aee3deSMauro Carvalho Chehab mantis->fe = fe;
18325aee3deSMauro Carvalho Chehab dprintk(MANTIS_ERROR, 1, "Done!");
18425aee3deSMauro Carvalho Chehab
18525aee3deSMauro Carvalho Chehab return 0;
18625aee3deSMauro Carvalho Chehab }
18725aee3deSMauro Carvalho Chehab
18825aee3deSMauro Carvalho Chehab struct mantis_hwconfig vp1033_config = {
18925aee3deSMauro Carvalho Chehab .model_name = MANTIS_MODEL_NAME,
19025aee3deSMauro Carvalho Chehab .dev_type = MANTIS_DEV_TYPE,
19125aee3deSMauro Carvalho Chehab .ts_size = MANTIS_TS_204,
19225aee3deSMauro Carvalho Chehab
19325aee3deSMauro Carvalho Chehab .baud_rate = MANTIS_BAUD_9600,
19425aee3deSMauro Carvalho Chehab .parity = MANTIS_PARITY_NONE,
19525aee3deSMauro Carvalho Chehab .bytes = 0,
19625aee3deSMauro Carvalho Chehab
19725aee3deSMauro Carvalho Chehab .frontend_init = vp1033_frontend_init,
19825aee3deSMauro Carvalho Chehab .power = GPIF_A12,
19925aee3deSMauro Carvalho Chehab .reset = GPIF_A13,
20025aee3deSMauro Carvalho Chehab };
201