Skip to content

Instantly share code, notes, and snippets.

@CvH

CvH/m88ds3103b.patch

Created Sep 12, 2018
Embed
What would you like to do?
m88ds3103b v2
From b32819e37711f40f136ce087e4176ab853f75863 Mon Sep 17 00:00:00 2001
From: CvH
Date: Wed, 12 Sep 2018 20:48:05 +0200
Subject: [PATCH] DS3103B patch
---
drivers/media/dvb-frontends/ds3000.c | 2217 ++++-
drivers/media/dvb-frontends/ds3000.h | 76 +-
drivers/media/dvb-frontends/ds3000_firmware.h | 8203 +++++++++++++++++
drivers/media/usb/dvb-usb/dw2102.c | 46 +-
4 files changed, 10287 insertions(+), 255 deletions(-)
mode change 100644 => 100755 drivers/media/dvb-frontends/ds3000.c
create mode 100755 drivers/media/dvb-frontends/ds3000_firmware.h
mode change 100644 => 100755 drivers/media/usb/dvb-usb/dw2102.c
diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c
old mode 100644
new mode 100755
index 2ff90e5e..e4b72e92
--- a/drivers/media/dvb-frontends/ds3000.c
+++ b/drivers/media/dvb-frontends/ds3000.c
@@ -1,8 +1,8 @@
/*
- Montage Technology DS3000 - DVBS/S2 Demodulator driver
- Copyright (C) 2009-2012 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
+ Montage Technology DS3000/TS2020 - DVBS/S2 Demodulator/Tuner driver
+ Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
- Copyright (C) 2009-2012 TurboSight.com
+ Copyright (C) 2009 TurboSight.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,10 +27,12 @@
#include <linux/firmware.h>
#include <media/dvb_frontend.h>
-#include "ts2020.h"
#include "ds3000.h"
+#include "ds3000_firmware.h"
+
+static int debug = 0;
+static int debugI2c = 0;
-static int debug;
#define dprintk(args...) \
do { \
@@ -38,20 +40,47 @@ static int debug;
printk(args); \
} while (0)
+#define I2Cprintk(args...) \
+ do { \
+ if (debugI2c) \
+ printk(args); \
+ } while (0)
+
+
/* as of March 2009 current DS3000 firmware version is 1.78 */
/* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */
#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw"
+#define DS300X_DEFAULT_FIRMWARE "dvb-fe-ds300x.fw"
+#define DS3103_DEFAULT_FIRMWARE "dvb-fe-ds3103.fw"
+
+#define TUNER_M88TS2020 0x2020
+#define TUNER_M88TS2022 0x2022
+#define TUNER_UNKNOW 0xFFFF
+
+typedef enum _MT_FE_DMD_ID
+{
+ FeDmdId_Undef,
+ FeDmdId_DS300X,
+ FeDmdId_DS3002B,
+ FeDmdId_DS3103,
+ FeDmdId_DS3103B,
+ FeDmdId_UNKNOW
+}MT_FE_DMD_ID;
+
#define DS3000_SAMPLE_RATE 96000 /* in kHz */
+#define DS3000_XTAL_FREQ 27000 /* in kHz */
+#define MT_FE_CRYSTAL_KHZ 27000 /* Crystal Frequency of M88TS2022 used, unit: KHz , range: 16000 - 32000 */
+
/* Register values to initialise the demod in DVB-S mode */
static u8 ds3000_dvbs_init_tab[] = {
0x23, 0x05,
0x08, 0x03,
- 0x0c, 0x00,
+ 0x0c, 0x02,
0x21, 0x54,
- 0x25, 0x82,
- 0x27, 0x31,
+ //0x25, 0x82,
+ //0x27, 0x31,
0x30, 0x08,
0x31, 0x40,
0x32, 0x32,
@@ -71,7 +100,7 @@ static u8 ds3000_dvbs_init_tab[] = {
0x52, 0x36,
0x53, 0x36,
0x56, 0x01,
- 0x63, 0x43,
+ 0x63, 0x47,
0x64, 0x30,
0x65, 0x40,
0x68, 0x26,
@@ -117,26 +146,108 @@ static u8 ds3000_dvbs_init_tab[] = {
0xc7, 0x0a,
0xc8, 0x1a,
0xc9, 0x80,
- 0xfe, 0x92,
+ 0xfe, 0xb6,
0xe0, 0xf8,
0xe6, 0x8b,
0xd0, 0x40,
0xf8, 0x20,
0xfa, 0x0f,
- 0xfd, 0x20,
0xad, 0x20,
0xae, 0x07,
- 0xb8, 0x00,
+ 0xb8, 0x00
+};
+static u8 ds310x_dvbs_init_tab[] = {
+ 0x23, 0x07,
+ 0x08, 0x03,
+ 0x0c, 0x02,
+ 0x21, 0x54,
+ //0x25, 0x82,
+ //0x27, 0x31,
+ 0x30, 0x08,
+ 0x31, 0x40,
+ 0x32, 0x32,
+ 0x33, 0x35,
+ 0x35, 0xff,
+ 0x3a, 0x00,
+ 0x37, 0x10,
+ 0x38, 0x10,
+ 0x39, 0x02,
+ 0x42, 0x60,
+ 0x4a, 0x80,
+ 0x4b, 0x04,
+ 0x4d, 0x91,
+ 0x5d, 0xc8,
+ 0x50, 0x36,
+ 0x51, 0x36,
+ 0x52, 0x36,
+ 0x53, 0x36,
+ 0x63, 0x0f,
+ 0x64, 0x30,
+ 0x65, 0x40,
+ 0x68, 0x26,
+ 0x69, 0x4c,
+ 0x70, 0x20,
+ 0x71, 0x70,
+ 0x72, 0x04,
+ 0x73, 0x00,
+ 0x70, 0x40,
+ 0x71, 0x70,
+ 0x72, 0x04,
+ 0x73, 0x00,
+ 0x70, 0x60,
+ 0x71, 0x70,
+ 0x72, 0x04,
+ 0x73, 0x00,
+ 0x70, 0x80,
+ 0x71, 0x70,
+ 0x72, 0x04,
+ 0x73, 0x00,
+ 0x70, 0xa0,
+ 0x71, 0x70,
+ 0x72, 0x04,
+ 0x73, 0x00,
+ 0x70, 0x1f,
+ 0x76, 0x38,
+ 0x77, 0xa6,
+ 0x78, 0x0c,
+ 0x79, 0x80,
+ 0x7f, 0x14,
+ 0x7c, 0x00,
+ 0xae, 0x82,
+ 0x80, 0x64,
+ 0x81, 0x66,
+ 0x82, 0x44,
+ 0x85, 0x04,
+ 0xcd, 0xf4,
+ 0x90, 0x33,
+ 0xa0, 0x44,
+ 0xbe, 0x00,
+ 0xc0, 0x08,
+ 0xc3, 0x10,
+ 0xc4, 0x08,
+ 0xc5, 0xf0,
+ 0xc6, 0xff,
+ 0xc7, 0x00,
+ 0xc8, 0x1a,
+ 0xc9, 0x80,
+ 0xe0, 0xf8,
+ 0xe6, 0x8b,
+ 0xd0, 0x40,
+ 0xf8, 0x20,
+ 0xfa, 0x0f,
+ 0x00, 0x00,
+ 0xbd, 0x01,
+ 0xb8, 0x00
};
/* Register values to initialise the demod in DVB-S2 mode */
static u8 ds3000_dvbs2_init_tab[] = {
0x23, 0x0f,
0x08, 0x07,
- 0x0c, 0x00,
+ 0x0c, 0x02,
0x21, 0x54,
- 0x25, 0x82,
- 0x27, 0x31,
+ //0x25, 0x82,
+ //0x27, 0x31,
0x30, 0x08,
0x31, 0x32,
0x32, 0x32,
@@ -149,7 +260,7 @@ static u8 ds3000_dvbs2_init_tab[] = {
0x42, 0x60,
0x4a, 0x80,
0x4b, 0x04,
- 0x4d, 0x81,
+ 0x4d, 0x91,
0x5d, 0x88,
0x50, 0x36,
0x51, 0x36,
@@ -195,6 +306,7 @@ static u8 ds3000_dvbs2_init_tab[] = {
0xca, 0x23,
0xcb, 0x24,
0xce, 0x74,
+ 0x56, 0x01,
0x90, 0x03,
0x76, 0x80,
0x77, 0x42,
@@ -224,27 +336,124 @@ static u8 ds3000_dvbs2_init_tab[] = {
0x8a, 0x10,
0xba, 0x00,
0xf5, 0x04,
- 0xfe, 0x44,
0xd2, 0x32,
- 0xb8, 0x00,
+ 0xb8, 0x00
+};
+static u8 ds310x_dvbs2_init_tab[] = {
+ 0x23, 0x07,
+ 0x08, 0x07,
+ 0x0c, 0x02,
+ 0x21, 0x54,
+ //0x25, 0x82,
+ //0x27, 0x31,
+ 0x30, 0x08,
+ 0x32, 0x32,
+ 0x33, 0x35,
+ 0x35, 0xff,
+ 0x3a, 0x00,
+ 0x37, 0x10,
+ 0x38, 0x10,
+ 0x39, 0x02,
+ 0x42, 0x60,
+ 0x4a, 0x80,
+ 0x4b, 0x04,
+ 0x4d, 0x91,
+ 0x5d, 0xc8,
+ 0x50, 0x36,
+ 0x51, 0x36,
+ 0x52, 0x36,
+ 0x53, 0x36,
+ 0x63, 0x0f,
+ 0x64, 0x10,
+ 0x65, 0x20,
+ 0x68, 0x46,
+ 0x69, 0xcd,
+ 0x70, 0x20,
+ 0x71, 0x70,
+ 0x72, 0x04,
+ 0x73, 0x00,
+ 0x70, 0x40,
+ 0x71, 0x70,
+ 0x72, 0x04,
+ 0x73, 0x00,
+ 0x70, 0x60,
+ 0x71, 0x70,
+ 0x72, 0x04,
+ 0x73, 0x00,
+ 0x70, 0x80,
+ 0x71, 0x70,
+ 0x72, 0x04,
+ 0x73, 0x00,
+ 0x70, 0xa0,
+ 0x71, 0x70,
+ 0x72, 0x04,
+ 0x73, 0x00,
+ 0x70, 0x1f,
+ 0x76, 0x38,
+ 0x77, 0xa6,
+ 0x78, 0x0c,
+ 0x79, 0x80,
+ 0x7f, 0x14,
+ 0x85, 0x08,
+ 0xcd, 0xf4,
+ 0x90, 0x33,
+ 0x86, 0x00,
+ 0x87, 0x0f,
+ 0x89, 0x00,
+ 0x8b, 0x44,
+ 0x8c, 0x66,
+ 0x9d, 0xc1,
+ 0x8a, 0x10,
+ 0xad, 0x40,
+ 0xa0, 0x44,
+ 0xbe, 0x00,
+ 0xc0, 0x08,
+ 0xc1, 0x10,
+ 0xc2, 0x08,
+ 0xc3, 0x10,
+ 0xc4, 0x08,
+ 0xc5, 0xf0,
+ 0xc6, 0xff,
+ 0xc7, 0x00,
+ 0xc8, 0x1a,
+ 0xc9, 0x80,
+ 0xca, 0x23,
+ 0xcb, 0x24,
+ 0xcc, 0xf4,
+ 0xce, 0x74,
+ 0x00, 0x00,
+ 0xbd, 0x01,
+ 0xb8, 0x00
};
struct ds3000_state {
struct i2c_adapter *i2c;
- const struct ds3000_config *config;
+ struct ds3000_config *config;
struct dvb_frontend frontend;
+ u8 skip_fw_load;
/* previous uncorrected block counter for DVB-S2 */
u16 prevUCBS2;
+ u16 chip_ID;
+ u16 tuner_ID;
+ u8 dt_addr; //For DS3103B
+ u8 cur_type;
+ int mclk_khz;
+ u32 cur_symbol_rate;
+ u32 cur_freqKhz;
};
static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
{
u8 buf[] = { reg, data };
- struct i2c_msg msg = { .addr = state->config->demod_address,
- .flags = 0, .buf = buf, .len = 2 };
+ struct i2c_msg msg = {
+ .addr = state->config->demod_address,
+ .flags = 0,
+ .buf = buf,
+ .len = 2
+ };
int err;
- dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
+ I2Cprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
err = i2c_transfer(state->i2c, &msg, 1);
if (err != 1) {
@@ -256,29 +465,19 @@ static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
return 0;
}
-static int ds3000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
- struct ds3000_state *state = fe->demodulator_priv;
-
- if (enable)
- ds3000_writereg(state, 0x03, 0x12);
- else
- ds3000_writereg(state, 0x03, 0x02);
-
- return 0;
-}
/* I2C write for 8k firmware load */
-static int ds3000_writeFW(struct ds3000_state *state, int reg,
- const u8 *data, u16 len)
+static int ds3000_writeFW(struct ds3000_state *state, int reg, const u8 *data, u16 len)
{
int i, ret = 0;
struct i2c_msg msg;
u8 *buf;
buf = kmalloc(33, GFP_KERNEL);
- if (!buf)
+ if (buf == NULL) {
+ printk(KERN_ERR "Unable to kmalloc\n");
return -ENOMEM;
+ }
*(buf) = reg;
@@ -290,12 +489,11 @@ static int ds3000_writeFW(struct ds3000_state *state, int reg,
for (i = 0; i < len; i += 32) {
memcpy(buf + 1, data + i, 32);
- dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
+ I2Cprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 1) {
- printk(KERN_ERR "%s: write error(err == %i, reg == 0x%02x\n",
- __func__, ret, reg);
+ printk(KERN_ERR "%s: write error(err == %i, reg == 0x%02x\n", __func__, ret, reg);
ret = -EREMOTEIO;
goto error;
}
@@ -325,85 +523,989 @@ static int ds3000_readreg(struct ds3000_state *state, u8 reg)
.buf = b1,
.len = 1
}
- };
+ };
+
+ ret = i2c_transfer(state->i2c, msg, 2);
+
+ if (ret != 2) {
+ printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
+ return ret;
+ }
+
+ I2Cprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
+
+ return b1[0];
+}
+
+static int ds3000_tuner_writereg(struct ds3000_state *state, int reg, int data)
+{
+ u8 buf[] = { reg, data };
+ struct i2c_msg msg = {
+ .addr = 0x60, .flags = 0, .buf = buf, .len = 2
+ };
+ int err;
+
+ I2Cprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
+
+ ds3000_writereg(state, 0x03, (ds3000_readreg(state, 0x03)&0xf8)|0x11);
+ err = i2c_transfer(state->i2c, &msg, 1);
+ if (err != 1) {
+ printk("%s: writereg error(err == %i, reg == 0x%02x,"
+ " value == 0x%02x)\n", __func__, err, reg, data);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg)
+{
+ int ret;
+ u8 b0[] = { reg };
+ u8 b1[] = { 0 };
+ struct i2c_msg msg[] = {
+ {
+ .addr = 0x60,
+ .flags = 0,
+ .buf = b0,
+ .len = 1
+ },
+ {
+ .addr = 0x60,
+ .flags = I2C_M_RD,
+ .buf = b1,
+ .len = 1
+ }
+ };
+
+ ds3000_writereg(state, 0x03, (ds3000_readreg(state, 0x03) & 0xf8) | 0x11);
+ ret = i2c_transfer(state->i2c, msg, 2);
+ if (ret != 2) {
+ printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
+ return ret;
+ }
+
+ I2Cprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
+
+ return b1[0];
+}
+
+static int ds3000_dt_write(struct ds3000_state *state, int reg, int data)
+{
+ int err;
+ u8 buf[] = {reg, data};
+ u8 val, tmp;
+ struct i2c_msg msg = {
+ .addr = state->dt_addr, .flags = 0, .buf = buf, .len = 2
+ };
+
+ tmp = ds3000_readreg(state, 0x11);
+ tmp &= ~0x01;
+ ds3000_writereg(state, 0x11, tmp);
+
+ val = 0x11;
+ ds3000_writereg(state, 0x03, val);
+ err = i2c_transfer(state->i2c, &msg, 1);
+ if (err != 1) {
+ printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
+ " value == 0x%02x)\n", __func__, err, reg, data);
+ return -EREMOTEIO;
+ }
+ tmp |= 0x01;
+ ds3000_writereg(state, 0x11, tmp);
+
+ return 0;
+}
+
+static int ds3000_dt_read(struct ds3000_state *state, u8 reg)
+{
+ u8 val, tmp;
+ int ret;
+ u8 b0[] = { reg };
+ u8 b1[] = { 0 };
+ struct i2c_msg msg[] = {
+ {
+ .addr = state->dt_addr,
+ .flags = 0,
+ .buf = b0,
+ .len = 1
+ },
+ {
+ .addr = state->dt_addr,
+ .flags = I2C_M_RD,
+ .buf = b1,
+ .len = 1
+ }
+ };
+
+ tmp = ds3000_readreg(state, 0x11);
+ tmp &= ~0x01;
+ ds3000_writereg(state, 0x11, tmp);
+
+ val = 0x12;
+ ds3000_writereg(state, 0x03, val);
+
+ ret = i2c_transfer(state->i2c, msg, 2);
+ if (ret != 2) {
+ printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
+ return -EREMOTEIO;;
+ }
+ tmp |= 0x01;
+ ds3000_writereg(state, 0x11, tmp);
+
+ return b1[0];
+}
+
+
+static int ds3000_load_firmware(struct dvb_frontend *fe,
+ const struct firmware *fw);
+
+static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
+{
+ struct ds3000_state *state = fe->demodulator_priv;
+ const struct firmware ds300x_fw = {ds300x_firmware_size, ds300x_firmware};
+ const struct firmware ds3103_fw = {ds3103_firmware_size, ds3103_firmware};
+ const struct firmware *fw;
+ int ret = 0;
+
+ dprintk("%s()\n", __func__);
+
+//xsj if(ds3000_readreg(state, 0xb2) <= 0)
+// return ret;
+
+ if (state->skip_fw_load)
+ return 0;
+ /* Load firmware */
+ if ((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B))
+ {
+ ds3000_writereg(state, 0x07, 0xE0); // global reset, global diseqc reset, golbal fec reset
+ ds3000_writereg(state, 0x07, 0x00);
+
+ /* request the firmware, this will block until someone uploads it */
+ printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
+ DS3103_DEFAULT_FIRMWARE);
+ fw = &ds3103_fw;
+ printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
+ }
+ else if(state->chip_ID==FeDmdId_DS300X)
+ {
+ /* request the firmware, this will block until someone uploads it */
+ printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
+ DS300X_DEFAULT_FIRMWARE);
+
+ fw = &ds300x_fw;
+ printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
+
+ }
+ else
+ {
+ printk(KERN_INFO "%s: unknow chip ID...\n", __func__);
+ return ret;
+ }
+
+ /* Make sure we don't recurse back through here during loading */
+ state->skip_fw_load = 1;
+
+ ret = ds3000_load_firmware(fe, fw);
+ if (ret)
+ printk("%s: Writing firmware to device failed\n", __func__);
+
+ //release_firmware(fw);
+
+ dprintk("%s: Firmware upload %s\n", __func__, ret == 0 ? "complete" : "failed");
+
+ /* Ensure firmware is always loaded if required */
+ state->skip_fw_load = 0;
+
+ return ret;
+}
+
+static int ds3000_load_firmware(struct dvb_frontend *fe,
+ const struct firmware *fw)
+{
+ struct ds3000_state *state = fe->demodulator_priv;
+
+ dprintk("%s\n", __func__);
+ dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
+ fw->size,
+ fw->data[0],
+ fw->data[1],
+ fw->data[fw->size - 2],
+ fw->data[fw->size - 1]);
+
+ /* Begin the firmware load process */
+ ds3000_writereg(state, 0xb2, 0x01);
+ /* write the entire firmware */
+ ds3000_writeFW(state, 0xb0, fw->data, fw->size);
+ ds3000_writereg(state, 0xb2, 0x00);
+
+ return 0;
+}
+
+
+
+/**************************************************************************
+* Function to Set the M88TS2022
+* fPLL: Frequency unit: MHz from 950 to 2150
+* fSym: SymbolRate unit: KS/s from 1000 to 45000
+* lpfOffset: Set the low pass filter offset when the demodulator set the PLL offset at low symbolrate unit: KHz
+* gainHold: The flag of AGC gain hold, the tuner gain is hold when gainHold == 1 , default please set gainHold = 0
+* return: Frequency offset of PLL unit: KHz
+**************************************************************************/
+
+int set_freq_ts2022(struct ds3000_state *state)
+{
+
+ u8 buf, capCode, div4, changePLL, K, lpf_mxdiv, divMax, divMin, RFgain = 0;
+ u32 gdiv28;
+ u32 N, lpf_gm, f3dB, fREF, divN, lpf_coeff = 3200;
+ s32 freqOffset;
+
+ u32 fPLL = (state->cur_freqKhz + 500) / 1000;
+ u32 fSym = state->cur_symbol_rate / 1000;
+ u16 lpfOffset = 0;
+ u8 gainHold = 0;
+
+
+ //Initialize the tuner
+ //InitialTuner();
+
+ //Set the PLL
+ if(fSym < 5000)
+ lpfOffset = 3000;
+
+ if(state->tuner_ID == TUNER_M88TS2020) {
+ ds3000_tuner_writereg(state, 0x10, 0x00);
+ } else if(state->tuner_ID == TUNER_M88TS2022) {
+ ds3000_tuner_writereg(state, 0x10, 0x0b);
+ ds3000_tuner_writereg(state, 0x11, 0x40);
+ } else {
+ printk(KERN_ERR "%s: Unable check tuner version\n", __func__);
+ return 1; //Error, maybe other tuner ICs,please do action at top level application
+ }
+
+ div4 = 0;
+ changePLL = 0;
+ K = 0;
+ divN = 0;
+ N = 0;
+ fREF = 2;
+
+ if(state->tuner_ID == TUNER_M88TS2020) {
+ K = (MT_FE_CRYSTAL_KHZ / 1000 + 1) / 2 - 8;
+ if(fPLL < 1146) {
+ ds3000_tuner_writereg(state, 0x10, 0x11);
+ div4 = 1;
+ divN = fPLL * (K + 8) * 4000 / MT_FE_CRYSTAL_KHZ;
+ } else {
+ ds3000_tuner_writereg(state, 0x10, 0x01);
+ divN = fPLL * (K + 8) * 2000 / MT_FE_CRYSTAL_KHZ;
+ }
+
+ divN =divN + divN % 2;
+ N = divN - 1024;
+ buf = (N >> 8) & 0x0f;
+ ds3000_tuner_writereg(state, 0x01, buf);
+
+ buf = N & 0xff;
+ ds3000_tuner_writereg(state, 0x02, buf);
+
+ buf = K;
+ ds3000_tuner_writereg(state, 0x03, buf);
+ } else if(state->tuner_ID == TUNER_M88TS2022) {
+ if(fREF == 1)
+ K = MT_FE_CRYSTAL_KHZ / 1000 - 8;
+ else
+ K = (MT_FE_CRYSTAL_KHZ / 1000 + 1) / 2 - 8;
+
+ if (fPLL < 1103) {
+ ds3000_tuner_writereg(state, 0x10, 0x1b);
+ div4 = 1;
+ divN = fPLL * (K+8) * 4000 / MT_FE_CRYSTAL_KHZ;
+ } else {
+ divN = fPLL * (K+8) * 2000 / MT_FE_CRYSTAL_KHZ;
+ }
+
+ divN = divN + divN % 2;
+
+ if (divN < 4095) {
+ N = divN - 1024;
+ } else if (divN < 6143) {
+ N = divN + 1024;
+ } else {
+ N = divN + 3072;
+ }
+
+ buf = (N >> 8) & 0x3f;
+ ds3000_tuner_writereg(state, 0x01, buf);
+
+ buf = N & 0xff;
+ ds3000_tuner_writereg(state, 0x02, buf);
+
+ buf = K;
+ ds3000_tuner_writereg(state, 0x03, buf);
+ }
+
+ ds3000_tuner_writereg(state, 0x51, 0x0f);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x10);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(5);
+
+ buf = ds3000_tuner_readreg(state, 0x15);
+ if((buf & 0x40) != 0x40) {
+ ds3000_tuner_writereg(state, 0x51, 0x0f);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x10);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(5);
+ }
+
+ if(state->tuner_ID == TUNER_M88TS2020) {
+ buf = ds3000_tuner_readreg(state, 0x66);
+ changePLL = (((buf & 0x80) >> 7) != div4);
+
+ if(changePLL)
+ {
+ ds3000_tuner_writereg(state, 0x10, 0x11);
+
+ div4 = 1;
+
+ divN = fPLL * (K + 8) * 4000 / MT_FE_CRYSTAL_KHZ;
+ divN = divN + divN % 2;
+ N = divN - 1024;
+
+ buf = (N >>8) & 0x0f;
+ ds3000_tuner_writereg(state, 0x01, buf);
+
+ buf = N & 0xff;
+ ds3000_tuner_writereg(state, 0x02, buf);
+
+ ds3000_tuner_writereg(state, 0x51, 0x0f);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x10);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(5);
+ }
+ } else if(state->tuner_ID == TUNER_M88TS2022) {
+ buf = ds3000_tuner_readreg(state, 0x14);
+ buf &= 0x7f;
+ if(buf < 64) {
+ buf = ds3000_tuner_readreg(state, 0x10);
+ buf |= 0x80;
+ ds3000_tuner_writereg(state, 0x10, buf);
+ ds3000_tuner_writereg(state, 0x11, 0x6f);
+
+ ds3000_tuner_writereg(state, 0x51, 0x0f);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x10);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(5);
+
+ buf = ds3000_tuner_readreg(state, 0x15);
+ if((buf & 0x40) != 0x40) {
+ ds3000_tuner_writereg(state, 0x51, 0x0f);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x10);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(5);
+ }
+ }
+
+ buf = ds3000_tuner_readreg(state, 0x14);
+ buf &= 0x1f;
+ if(buf > 19) {
+ buf = ds3000_tuner_readreg(state, 0x10);
+ buf &= 0xfd;
+ ds3000_tuner_writereg(state, 0x10, buf);
+ }
+ }
+
+ freqOffset = (s32)(divN * MT_FE_CRYSTAL_KHZ / (K + 8)/(div4 + 1) / 2 - fPLL * 1000);
+
+ // set the RF gain
+ if(state->tuner_ID == TUNER_M88TS2020) {
+ ds3000_tuner_writereg(state, 0x60, 0x79);
+ }
+
+ ds3000_tuner_writereg(state, 0x51, 0x17);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x08);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(5);
+
+ buf = ds3000_tuner_readreg(state, 0x3c);
+ if(buf == 0) {
+ ds3000_tuner_writereg(state, 0x51, 0x17);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x08);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(5);
+ }
+
+ if(state->tuner_ID == TUNER_M88TS2020) {
+ buf = ds3000_tuner_readreg(state, 0x3d);
+ RFgain = buf & 0x0f;
+
+ if(RFgain < 15) {
+ if(RFgain < 4)
+ RFgain = 0;
+ else
+ RFgain = RFgain - 3;
+
+ buf = ((RFgain << 3) | 0x01) & 0x79;
+ ds3000_tuner_writereg(state, 0x60, buf);
+
+ ds3000_tuner_writereg(state, 0x51, 0x17);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x08);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(5);
+ }
+ }
+
+ // set the LPF
+ if(state->tuner_ID == TUNER_M88TS2022) {
+ ds3000_tuner_writereg(state, 0x25, 0x00);
+ ds3000_tuner_writereg(state, 0x27, 0x70);
+ ds3000_tuner_writereg(state, 0x41, 0x09);
+
+ ds3000_tuner_writereg(state, 0x08, 0x0b);
+ }
+
+ f3dB = fSym * 135 / 200 + 2000;
+
+ f3dB += lpfOffset;
+
+ if(f3dB < 7000) f3dB = 7000;
+ if(f3dB > 40000) f3dB = 40000;
+
+ gdiv28 = (MT_FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000;
+
+ buf = (u8)gdiv28;
+ ds3000_tuner_writereg(state, 0x04, buf);
+
+ ds3000_tuner_writereg(state, 0x51, 0x1b);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x04);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(2);
+
+ buf = ds3000_tuner_readreg(state, 0x26);
+ if(buf == 0x00) {
+ ds3000_tuner_writereg(state, 0x51, 0x1b);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x04);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(2);
+
+ buf = ds3000_tuner_readreg(state, 0x26);
+ }
+
+ capCode = buf & 0x3f;
+ if(state->tuner_ID == TUNER_M88TS2022) {
+ ds3000_tuner_writereg(state, 0x41, 0x0d);
+
+ ds3000_tuner_writereg(state, 0x51, 0x1b);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x04);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(2);
+ buf = ds3000_tuner_readreg(state, 0x26);
+ if(buf == 0x00) {
+ ds3000_tuner_writereg(state, 0x51, 0x1b);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x04);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(2);
+ buf = ds3000_tuner_readreg(state, 0x26);
+ }
+
+ buf &= 0x3f;
+ capCode = (capCode + buf) / 2;
+ }
+
+ gdiv28 = gdiv28 * 207 / (capCode * 2 + 151);
+
+ divMax = gdiv28 * 135 / 100;
+ divMin = gdiv28 * 78 / 100;
+
+ if(divMax > 63)
+ divMax = 63;
+
+ if(state->tuner_ID == TUNER_M88TS2020) {
+ lpf_coeff = 2766;
+ } else if(state->tuner_ID == TUNER_M88TS2022) {
+ lpf_coeff = 3200;
+ }
+
+ lpf_gm = (f3dB * gdiv28 * 2 / lpf_coeff / (MT_FE_CRYSTAL_KHZ / 1000) + 1) / 2;
+
+ if (lpf_gm > 23)
+ lpf_gm = 23;
+ if (lpf_gm < 1)
+ lpf_gm = 1;
+
+ lpf_mxdiv = (lpf_gm * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3dB + 1) / 2;
+
+ if (lpf_mxdiv < divMin) {
+ lpf_gm++;
+ lpf_mxdiv = (lpf_gm * (MT_FE_CRYSTAL_KHZ / 1000) * lpf_coeff * 2 / f3dB + 1) / 2;
+ }
+
+ if (lpf_mxdiv > divMax) {
+ lpf_mxdiv = divMax;
+ }
+
+ buf = lpf_mxdiv;
+ ds3000_tuner_writereg(state, 0x04, buf);
+
+ buf = lpf_gm;
+ ds3000_tuner_writereg(state, 0x06, buf);
+
+ ds3000_tuner_writereg(state, 0x51, 0x1b);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x04);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(2);
+
+ buf = ds3000_tuner_readreg(state, 0x26);
+ if(buf == 0x00) {
+ ds3000_tuner_writereg(state, 0x51, 0x1b);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x04);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(2);
+
+ buf = ds3000_tuner_readreg(state, 0x26);
+ }
+
+ if(state->tuner_ID == TUNER_M88TS2022)
+ {
+ capCode = buf & 0x3f;
+
+ ds3000_tuner_writereg(state, 0x41, 0x09);
+
+ ds3000_tuner_writereg(state, 0x51, 0x1b);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x04);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(2);
+
+ buf = ds3000_tuner_readreg(state, 0x26);
+ if(buf == 0x00) {
+ ds3000_tuner_writereg(state, 0x51, 0x1b);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x04);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(2);
+
+ buf = ds3000_tuner_readreg(state, 0x26);
+ }
+
+ buf &= 0x3f;
+ capCode = (capCode + buf) / 2;
+
+ buf = capCode | 0x80;
+ ds3000_tuner_writereg(state, 0x25, buf);
+ ds3000_tuner_writereg(state, 0x27, 0x30);
+
+ ds3000_tuner_writereg(state, 0x08, 0x09);
+ }
+
+ // Set the BB gain
+ // default should set gainHold = 0;
+ // except when the AGC of demodulator is hold, for example application at blind scan use Haier demodulator
+
+ if(gainHold == 0) {
+ ds3000_tuner_writereg(state, 0x51, 0x1e);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x01);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(20);
+
+ buf = ds3000_tuner_readreg(state, 0x21);
+ if(buf == 0x00) {
+ ds3000_tuner_writereg(state, 0x51, 0x1e);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x01);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(20);
+ }
+
+ if(state->tuner_ID == TUNER_M88TS2020) {
+ if(RFgain == 15) {
+ msleep(20);
+ buf = ds3000_tuner_readreg(state, 0x21);
+ buf &= 0x0f;
+ if(buf < 3) {
+ ds3000_tuner_writereg(state, 0x60, 0x61);
+
+ ds3000_tuner_writereg(state, 0x51, 0x17);
+ ds3000_tuner_writereg(state, 0x51, 0x1f);
+ ds3000_tuner_writereg(state, 0x50, 0x08);
+ ds3000_tuner_writereg(state, 0x50, 0x00);
+ msleep(20);
+ }
+ }
+ }
+
+ //User should delay 100ms here to wait the Tuner gain stable before checking the chip lock status
+ //If there have delay time at the function of setting demodulator, you can take out it to reduce the lock time;
+ msleep(40);
+ }
+
+ return freqOffset; // return the frequency offset : KHz
+}
+
+int _mt_fe_dmd_ds3k_select_mclk(struct ds3000_state *state)
+{
+ u32 adc_Freq_MHz[3] = {96, 93, 99};
+ u8 reg16_list[3] = {96, 92, 100}, reg16, reg15;
+ u32 offset_MHz[3];
+ u32 max_offset = 0;
+ u32 tuner_freq_MHz = state->cur_freqKhz / 1000;
+
+ u8 i;
+
+ char bBigSymbol = 0;
+
+ bBigSymbol = (state->cur_symbol_rate > 45010000) ? 1 : 0;
+
+ if(bBigSymbol) {
+ #if 0
+ adc_Freq_MHz[0] = 216;
+ adc_Freq_MHz[1] = 222;
+ adc_Freq_MHz[2] = 219;
+
+ reg16_list[0] = 112;
+ reg16_list[1] = 116;
+ reg16_list[2] = 114;
+ #endif
+
+ reg16 = 115; //147 - 32;
+ state->mclk_khz = 110250;
+ } else {
+ adc_Freq_MHz[0] = 96;
+ adc_Freq_MHz[1] = 93;
+ adc_Freq_MHz[2] = 99;
+
+ reg16_list[0] = 96;
+ reg16_list[1] = 92;
+ reg16_list[2] = 100;
+
+ reg16 = 96;
+
+ for(i = 0; i < 3; i++)
+ {
+ offset_MHz[i] = tuner_freq_MHz % adc_Freq_MHz[i];
+
+ if(offset_MHz[i] > (adc_Freq_MHz[i] / 2))
+ offset_MHz[i] = adc_Freq_MHz[i] - offset_MHz[i];
+
+ if(offset_MHz[i] > max_offset)
+ {
+ max_offset = offset_MHz[i];
+ reg16 = reg16_list[i];
+ state->mclk_khz= adc_Freq_MHz[i] * 1000;
+
+ if(bBigSymbol)
+ state->mclk_khz /= 2;
+ }
+ }
+ }
- ret = i2c_transfer(state->i2c, msg, 2);
+ if(state->mclk_khz == 93000)
+ ds3000_writereg(state, 0xA0, 0x42);
+ else if(state->mclk_khz == 96000)
+ ds3000_writereg(state, 0xA0, 0x44);
+ else if(state->mclk_khz == 99000)
+ ds3000_writereg(state, 0xA0, 0x46);
+ else if(state->mclk_khz == 110250)
+ ds3000_writereg(state, 0xA0, 0x4E);
+ else
+ ds3000_writereg(state, 0xA0, 0x44);
- if (ret != 2) {
- printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
- return ret;
+ reg15 = ds3000_dt_read(state, 0x15);
+
+ ds3000_dt_write(state, 0x05, 0x40);
+ ds3000_dt_write(state, 0x11, 0x08);
+
+ if(bBigSymbol) {
+ reg15 |= 0x02;
+ } else {
+ reg15 &= ~0x02;
}
+ ds3000_dt_write(state, 0x15, reg15);
- dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
+ ds3000_dt_write(state, 0x16, reg16);
- return b1[0];
-}
+ msleep(5);
-static int ds3000_load_firmware(struct dvb_frontend *fe,
- const struct firmware *fw);
+ ds3000_dt_write(state, 0x05, 0x00);
+ ds3000_dt_write(state, 0x11, (u8)(bBigSymbol ? 0x0E : 0x0A));
+ msleep(5);
-static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
+ return 0;
+}
+
+int _mt_fe_dmd_ds3k_set_mclk(struct ds3000_state *state, u32 MCLK_KHz)
{
- struct ds3000_state *state = fe->demodulator_priv;
- const struct firmware *fw;
- int ret = 0;
+ u8 tmp3 = 0, tmp4 = 0;
+ struct ds3000_config *cfg = state->config;
+
+ if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)) {
+ // 0x22 bit[7:6] clkxM_d
+ tmp3 = ds3000_readreg(state, 0x22);
+ // 0x24 bit[7:6] clkxM_sel
+ tmp4 = ds3000_readreg(state, 0x24);
+
+ switch(MCLK_KHz) {
+ case 192000: // 4b'0011 MCLK = 192M
+ tmp3 |= 0xc0; // 0x22 bit[7:6] = 2b'11
+ tmp4 &= 0x3f; // 0x24 bit[7:6] = 2b'00
+ break;
+
+ case 144000: // 4b'0100 MCLK = 144M
+ tmp3 &= 0x3f; // 0x22 bit[7:6] = 2b'00
+ tmp4 &= 0x7f; // 0x24 bit[7:6] = 2b'01
+ tmp4 |= 0x40;
+ break;
+
+ case 115200: // 4b'0101 MCLK = 115.2M
+ tmp3 &= 0x7f; // 0x22 bit[7:6] = 2b'01
+ tmp3 |= 0x40;
+ tmp4 &= 0x7f; // 0x24 bit[7:6] = 2b'01
+ tmp4 |= 0x40;
+ break;
+
+ case 72000: // 4b'1100 MCLK = 72M
+ tmp4 |= 0xc0; // 0x24 bit[7:6] = 2b'11
+ tmp3 &= 0x3f; // 0x22 bit[7:6] = 2b'00
+ break;
+
+ case 96000: // 4b'0110 MCLK = 96M
+ default:
+ tmp3 &= 0xbf; // 0x22 bit[7:6] = 2b'10
+ tmp3 |= 0x80;
+
+ tmp4 &= 0x7f; // 0x24 bit[7:6] = 2b'01
+ tmp4 |= 0x40;
+ break;
+ }
- dprintk("%s()\n", __func__);
+ ds3000_writereg(state, 0x22, tmp3);
+ ds3000_writereg(state, 0x24, tmp4);
+ } else if(state->chip_ID == FeDmdId_DS3103B) {
+ u8 reg11 = 0x0A, reg15, reg16, reg1D, reg1E, reg1F, tmp;
+ u8 sm, f0 = 0, f1 = 0, f2 = 0, f3 = 0, pll_ldpc_mode;
+ u16 pll_div_fb, N;
+ u32 div;
+
+ reg15 = ds3000_dt_read(state, 0x15);
+ reg16 = ds3000_dt_read(state, 0x16);
+ reg1D = ds3000_dt_read(state, 0x1D);
+
+
+ if(cfg->output_mode != MtFeTsOutMode_Serial) {
+ #if 1 // 130603
+ if(reg16 == 92)
+ {
+ tmp = 93;
+ }
+ else if(reg16 == 100)
+ {
+ tmp = 99;
+ }
+ else // if(reg16 == 96)
+ {
+ tmp = 96;
+ }
+
+ MCLK_KHz *= tmp;
+ MCLK_KHz /= 96;
+ #endif
+ }
- ret = ds3000_readreg(state, 0xb2);
- if (ret < 0)
- return ret;
- /* Load firmware */
- /* request the firmware, this will block until someone uploads it */
- printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
- DS3000_DEFAULT_FIRMWARE);
- ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
- state->i2c->dev.parent);
- printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
- if (ret) {
- printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n",
- __func__);
- return ret;
- }
+ pll_ldpc_mode = (reg15 >> 1) & 0x01;
+
+ //pll_div_fb = (pll_ldpc_mode == 1) ? 147 : 128;
+ //pll_div_fb -= 32;
+ pll_div_fb = (reg15 & 0x01) << 8;
+ pll_div_fb += reg16;
+ pll_div_fb += 32;
+
+ div = 9000 * pll_div_fb * 4;
+ div /= MCLK_KHz;
+
+
+ if(cfg->output_mode == MtFeTsOutMode_Serial) {
+ reg11 |= 0x02;
+
+ if(div <= 32)
+ {
+ N = 2;
+
+ f0 = 0;
+ f1 = div / N;
+ f2 = div - f1;
+ f3 = 0;
+ }
+ else if(div <= 34)
+ {
+ N = 3;
+
+ f0 = div / N;
+ f1 = (div - f0) / (N - 1);
+ f2 = div - f0 - f1;
+ f3 = 0;
+ }
+ else if(div <= 64)
+ {
+ N = 4;
+
+ f0 = div / N;
+ f1 = (div - f0) / (N - 1);
+ f2 = (div - f0 - f1) / (N - 2);
+ f3 = div - f0 - f1 - f2;
+ }
+ else
+ {
+ N = 4;
+
+ f0 = 16;
+ f1 = 16;
+ f2 = 16;
+ f3 = 16;
+ }
+
+
+ if(f0 == 16)
+ f0 = 0;
+ else if((f0 < 8) && (f0 != 0))
+ f0 = 8;
+
+ if(f1 == 16)
+ f1 = 0;
+ else if((f1 < 8) && (f1 != 0))
+ f1 = 8;
+
+ if(f2 == 16)
+ f2 = 0;
+ else if((f2 < 8) && (f2 != 0))
+ f2 = 8;
+
+ if(f3 == 16)
+ f3 = 0;
+ else if((f3 < 8) && (f3 != 0))
+ f3 = 8;
+ }
+ else
+ {
+ reg11 &= ~0x02;
+
+ if(div <= 32)
+ {
+ N = 2;
+
+ f0 = 0;
+ f1 = div / N;
+ f2 = div - f1;
+ f3 = 0;
+ }
+ else if(div <= 48)
+ {
+ N = 3;
+
+ f0 = div / N;
+ f1 = (div - f0) / (N - 1);
+ f2 = div - f0 - f1;
+ f3 = 0;
+ }
+ else if(div <= 64)
+ {
+ N = 4;
+
+ f0 = div / N;
+ f1 = (div - f0) / (N - 1);
+ f2 = (div - f0 - f1) / (N - 2);
+ f3 = div - f0 - f1 - f2;
+ }
+ else
+ {
+ N = 4;
+
+ f0 = 16;
+ f1 = 16;
+ f2 = 16;
+ f3 = 16;
+ }
+
+ if(f0 == 16)
+ f0 = 0;
+ else if((f0 < 9) && (f0 != 0))
+ f0 = 9;
+
+ if(f1 == 16)
+ f1 = 0;
+ else if((f1 < 9) && (f1 != 0))
+ f1 = 9;
+
+ if(f2 == 16)
+ f2 = 0;
+ else if((f2 < 9) && (f2 != 0))
+ f2 = 9;
+
+ if(f3 == 16)
+ f3 = 0;
+ else if((f3 < 9) && (f3 != 0))
+ f3 = 9;
+ }
- ret = ds3000_load_firmware(fe, fw);
- if (ret)
- printk("%s: Writing firmware to device failed\n", __func__);
+ sm = N - 1;
- release_firmware(fw);
+ /* Write to registers */
+ //reg15 &= 0x01;
+ //reg15 |= (pll_div_fb >> 8) & 0x01;
- dprintk("%s: Firmware upload %s\n", __func__,
- ret == 0 ? "complete" : "failed");
+ //reg16 = pll_div_fb & 0xFF;
- return ret;
-}
+ reg1D &= ~0x03;
+ reg1D |= sm;
+ reg1D |= 0x80;
-static int ds3000_load_firmware(struct dvb_frontend *fe,
- const struct firmware *fw)
-{
- struct ds3000_state *state = fe->demodulator_priv;
- int ret = 0;
+ reg1E = ((f3 << 4) + f2) & 0xFF;
+ reg1F = ((f1 << 4) + f0) & 0xFF;
- dprintk("%s\n", __func__);
- dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
- fw->size,
- fw->data[0],
- fw->data[1],
- fw->data[fw->size - 2],
- fw->data[fw->size - 1]);
+ ds3000_dt_write(state, 0x05, 0x40);
+ ds3000_dt_write(state, 0x11, 0x08);
+ ds3000_dt_write(state, 0x1D, reg1D);
+ ds3000_dt_write(state, 0x1E, reg1E);
+ ds3000_dt_write(state, 0x1F, reg1F);
- /* Begin the firmware load process */
- ds3000_writereg(state, 0xb2, 0x01);
- /* write the entire firmware */
- ret = ds3000_writeFW(state, 0xb0, fw->data, fw->size);
- ds3000_writereg(state, 0xb2, 0x00);
+ ds3000_dt_write(state, 0x17, 0xc1);
+ ds3000_dt_write(state, 0x17, 0x81);
+ msleep(5);
- return ret;
+ ds3000_dt_write(state, 0x05, 0x00);
+ ds3000_dt_write(state, 0x11, 0x0A);
+ msleep(5);
+ }
+ else if(state->chip_ID == FeDmdId_DS300X)
+ {
+ return -4;
+ }
+ else
+ {
+ return -6;
+ }
+
+ return 0;
}
-static int ds3000_set_voltage(struct dvb_frontend *fe,
- enum fe_sec_voltage voltage)
+static int ds3000_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
{
struct ds3000_state *state = fe->demodulator_priv;
u8 data;
@@ -456,13 +1558,13 @@ static int ds3000_read_status(struct dvb_frontend *fe, enum fe_status *status)
break;
default:
- return -EINVAL;
+ return 1;
}
if (state->config->set_lock_led)
state->config->set_lock_led(fe, *status == 0 ? 0 : 1);
- dprintk("%s: status = 0x%02x\n", __func__, lock);
+ dprintk("%s: lock = 0x%02x, status = 0x%02x\n", __func__, lock, *status);
return 0;
}
@@ -526,17 +1628,68 @@ static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
*ber = 0xffffffff;
break;
default:
- return -EINVAL;
+ return 1;
}
return 0;
}
+/* read TS2020 signal strength */
static int ds3000_read_signal_strength(struct dvb_frontend *fe,
u16 *signal_strength)
{
- if (fe->ops.tuner_ops.get_rf_strength)
- fe->ops.tuner_ops.get_rf_strength(fe, signal_strength);
+ struct ds3000_state *state = fe->demodulator_priv;
+ int sig_reading = 0;
+ u8 rfgain, bbgain, nngain;
+ u8 rfagc;
+ u32 gain = 0;
+ dprintk("%s()\n", __func__);
+
+ rfgain = ds3000_tuner_readreg(state, 0x3d) & 0x1f;
+ bbgain = ds3000_tuner_readreg(state, 0x21) & 0x1f;
+ rfagc = ds3000_tuner_readreg(state, 0x3f);
+
+ if(state->tuner_ID == TUNER_M88TS2020)
+ {
+ //TUNER 2020
+ sig_reading = rfagc * 20 - 1166;
+ if(sig_reading<0) sig_reading =0;
+ if(rfgain < 0) rfgain = 0;
+ if(rfgain > 15) rfgain = 15;
+ if(bbgain < 0 ) bbgain = 0;
+ if(bbgain > 13) bbgain = 13;
+
+ if(sig_reading < 400) sig_reading = 400;
+ if(sig_reading > 1100) sig_reading = 1100;
+
+ gain = (u16) rfgain * 233 + (u16) bbgain * 350 + sig_reading * 24 / 10 + 1000;
+
+ }
+ else if(state->tuner_ID == TUNER_M88TS2022)
+ {
+ //TUNER 2022
+ sig_reading = rfagc * 16 - 670;
+ if(sig_reading<0) sig_reading = 0;
+ nngain =ds3000_tuner_readreg(state, 0x66);
+ nngain = (nngain >> 3) & 0x07;
+
+ if(rfgain < 0) rfgain = 0;
+ if(rfgain > 15) rfgain = 15;
+ if(bbgain < 2) bbgain = 2;
+ if(bbgain > 16) bbgain = 16;
+ if(nngain < 0) nngain = 0;
+ if(nngain > 6) nngain = 6;
+
+ if(sig_reading < 600) sig_reading = 600;
+ if(sig_reading > 1600) sig_reading = 1600;
+
+ gain = (u16) rfgain * 265 + (u16) bbgain * 338 + (u16) nngain * 285 + sig_reading * 176 / 100 - 3000;
+ }
+
+
+ *signal_strength = gain*100;
+
+ dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__, sig_reading, *signal_strength);
return 0;
}
@@ -615,13 +1768,13 @@ static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
snr_reading = dvbs2_noise_reading / tmp;
if (snr_reading > 80)
snr_reading = 80;
- *snr = -(dvbs2_snr_tab[snr_reading - 1] / 1000);
+ *snr = -(dvbs2_snr_tab[snr_reading] / 1000);
}
dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
snr_reading, *snr);
break;
default:
- return -EINVAL;
+ return 1;
}
return 0;
@@ -659,7 +1812,7 @@ static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
state->prevUCBS2 = _ucblocks;
break;
default:
- return -EINVAL;
+ return 1;
}
return 0;
@@ -717,6 +1870,7 @@ static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
/* enable DiSEqC message send pin */
data = ds3000_readreg(state, 0xa2);
data &= ~0xc0;
+ data &= ~0x20;
ds3000_writereg(state, 0xa2, data);
/* DiSEqC message */
@@ -752,7 +1906,7 @@ static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
data |= 0x80;
ds3000_writereg(state, 0xa2, data);
- return -ETIMEDOUT;
+ return 1;
}
data = ds3000_readreg(state, 0xa2);
@@ -764,8 +1918,7 @@ static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
}
/* Send DiSEqC burst */
-static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
- enum fe_sec_mini_cmd burst)
+static int ds3000_diseqc_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst)
{
struct ds3000_state *state = fe->demodulator_priv;
int i;
@@ -775,6 +1928,7 @@ static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
data = ds3000_readreg(state, 0xa2);
data &= ~0xc0;
+ data &= ~0x20;
ds3000_writereg(state, 0xa2, data);
/* DiSEqC burst */
@@ -806,7 +1960,7 @@ static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
data |= 0x80;
ds3000_writereg(state, 0xa2, data);
- return -ETIMEDOUT;
+ return 1;
}
data = ds3000_readreg(state, 0xa2);
@@ -828,51 +1982,113 @@ static void ds3000_release(struct dvb_frontend *fe)
kfree(state);
}
-static const struct dvb_frontend_ops ds3000_ops;
+static struct dvb_frontend_ops ds3000_ops;
-struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+struct dvb_frontend *ds3000_attach(struct ds3000_config *config,
struct i2c_adapter *i2c)
{
- struct ds3000_state *state;
+ struct ds3000_state *state = NULL;
int ret;
+ u8 val_00, val_01, val_02, val_b2;
+ int i;
+
dprintk("%s\n", __func__);
/* allocate memory for the internal state */
- state = kzalloc(sizeof(*state), GFP_KERNEL);
- if (!state)
- return NULL;
+ state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
+ if (state == NULL) {
+ printk(KERN_ERR "Unable to kmalloc\n");
+ goto error2;
+ }
state->config = config;
state->i2c = i2c;
state->prevUCBS2 = 0;
+ state->dt_addr = 0x42;
+ state->cur_type = SYS_DVBS;
/* check if the demod is present */
- ret = ds3000_readreg(state, 0x00) & 0xfe;
- if (ret != 0xe0) {
- kfree(state);
+ for(i = 0x68; i <= 0x6b; i++) {
+ state->config->demod_address = i;
+ ret = ds3000_readreg(state, 0x00) & 0xfe;
+ if((ret == 0xE0) || (ret == 0xE8 ))
+ break;
+ }
+ if((i == 0x6b ) && (ret != 0xE0) && (ret != 0xE8 )) {
printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
- return NULL;
+ goto error3;
}
printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
ds3000_readreg(state, 0x02),
ds3000_readreg(state, 0x01));
- memcpy(&state->frontend.ops, &ds3000_ops,
- sizeof(struct dvb_frontend_ops));
- state->frontend.demodulator_priv = state;
+ /* check demod chip ID */
+ val_00 = ds3000_readreg(state, 0x00);
+ val_01 = ds3000_readreg(state, 0x01);
+ val_02 = ds3000_readreg(state, 0x02);
+ val_b2 = ds3000_readreg(state, 0xb2);
+ if((val_02 == 0x00) && (val_01 == 0xC0))
+ {
+ state->chip_ID = FeDmdId_DS300X;
+ printk("\tChip ID = [DS300X]!\n");
+ }
+ else if((val_02 == 0x00) && (val_01 == 0xD0) && ((val_b2 & 0xC0) == 0x00))
+ {
+ state->chip_ID = FeDmdId_DS3002B;
+ printk("\tChip ID = [DS3002B]!\n");
+ }
+ else if((val_02 == 0x00) && (val_01 == 0xD0) && ((val_b2 & 0xC0) == 0xC0))
+ {
+ state->chip_ID = FeDmdId_DS3103;
+ printk("\tChip ID = [DS3103]!\n");
+ }
+ else if((val_02 == 0x00) && ((val_01 == 0xA0) || (val_01 == 0xA1))
+ && ((val_b2 & 0xC0) == 0x00) && (val_00 == 0xE8))
+ {
+ state->chip_ID = FeDmdId_DS3103B;
+ printk("\tChip ID = [DS3103B]!\n");
+ }
+ else
+ {
+ state->chip_ID = FeDmdId_UNKNOW;
+ printk("\tChip ID = unknow!\n");
+ }
+
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ val_00 = ds3000_readreg(state, 0x29);
+ state->dt_addr = ((val_00 & 0x80) == 0) ? 0x42 : 0x40;
+ printk("dt addr is 0x%02x", state->dt_addr);
+ }
- /*
- * Some devices like T480 starts with voltage on. Be sure
- * to turn voltage off during init, as this can otherwise
- * interfere with Unicable SCR systems.
- */
- ds3000_set_voltage(&state->frontend, SEC_VOLTAGE_OFF);
+ memcpy(&state->frontend.ops, &ds3000_ops, sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
return &state->frontend;
+
+error3:
+ kfree(state);
+error2:
+ return NULL;
}
EXPORT_SYMBOL(ds3000_attach);
+#if 0
+static int ds3000_set_property(struct dvb_frontend *fe,
+ struct dtv_property *tvp)
+{
+ dprintk("%s(..)\n", __func__);
+ return 0;
+}
+
+static int ds3000_get_property(struct dvb_frontend *fe,
+ struct dtv_property *tvp)
+{
+ dprintk("%s(..)\n", __func__);
+ return 0;
+}
+#endif
+
static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
s32 carrier_offset_khz)
{
@@ -892,149 +2108,371 @@ static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
return 0;
}
+static int ds3000_setTSdiv(struct ds3000_state *state, int type, u8 tmp1, u8 tmp2)
+{
+ u8 buf;
+ if(type == SYS_DVBS) {
+ if(state->chip_ID == FeDmdId_DS300X) {
+ tmp1 &= 0x07;
+ tmp2 &= 0x07;
+ buf = ds3000_readreg(state, 0xfe);
+ buf &= 0xc0;
+ buf |= ((u8)(((tmp1<<3) + tmp2)) & 0x3f);
+ ds3000_writereg(state, 0xfe, buf);
+ } else if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B)) {
+ tmp1 -= 1;
+ tmp2 -= 1;
+
+ tmp1 &= 0x3f;
+ tmp2 &= 0x3f;
+
+ buf = ds3000_readreg(state, 0xfe);
+ buf &= 0xF0;
+ buf |= (tmp1 >> 2) & 0x0f;
+ ds3000_writereg(state, 0xfe, buf);
+
+ buf = (u8)((tmp1 & 0x03) << 6);
+ buf |= tmp2;
+ ds3000_writereg(state, 0xea, buf);
+ } else {
+ return -1;
+ }
+ } else if(type == SYS_DVBS2) {
+ if(state->chip_ID == FeDmdId_DS300X) {
+ tmp1 &= 0x0f;
+ tmp2 &= 0x0f;
+ buf = (u8)((tmp1<<4) + tmp2);
+ ds3000_writereg(state, 0xfe, buf);
+ } else if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B)) {
+ tmp1 -= 1;
+ tmp2 -= 1;
+
+ tmp1 &= 0x3f;
+ tmp2 &= 0x3f;
+
+
+ buf = ds3000_readreg(state, 0xfe);
+ buf &= 0xF0; // bits[3:0]
+ buf |= (tmp1 >> 2) & 0x0f;
+ ds3000_writereg(state, 0xfe, buf);
+
+ buf = (u8)((tmp1 & 0x03) << 6); // ci_divrange_h_0 bits[1:0]
+ buf |= tmp2; // ci_divrange_l bits[5:0]
+ ds3000_writereg(state, 0xea, buf);
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+}
static int ds3000_set_frontend(struct dvb_frontend *fe)
{
struct ds3000_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct ds3000_config *cfg = state->config;
int i;
enum fe_status status;
s32 offset_khz;
- u32 frequency;
u16 value;
+ u32 tmp;
+ u8 tmp1, tmp2;
+ u32 target_mclk = 0;
+ u32 ts_clk = 24000;
+ u16 divide_ratio;
- dprintk("%s() ", __func__);
+ state->cur_type = c->delivery_system;
+ state->cur_symbol_rate = c->symbol_rate;
+ state->cur_freqKhz = c->frequency;
+
+ dprintk("%s() frec=%d symb=%d", __func__, c->frequency, c->symbol_rate);
if (state->config->set_ts_params)
state->config->set_ts_params(fe, 0);
- /* Tune */
- if (fe->ops.tuner_ops.set_params)
- fe->ops.tuner_ops.set_params(fe);
+ //
+ if(state->chip_ID == FeDmdId_DS300X) {
+ value = ds3000_readreg(state, 0xb2);
+ if(value == 0x01) {
+ ds3000_writereg(state, 0x05, 0x00);
+ ds3000_writereg(state, 0xb2, 0x00);
+ }
+ } else if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B)) {
+ value = ds3000_readreg(state, 0xb2);
+ if(value == 0x01) {
+ ds3000_writereg(state, 0x00, 0x00);
+ ds3000_writereg(state, 0xb2, 0x00);
+ }
+ } else {
+ printk(KERN_ERR "%s: Unable check tuner version\n", __func__);
+ return -1; //Error, maybe other tuner ICs,please do action at top level application
+ }
- /* ds3000 global reset */
- ds3000_writereg(state, 0x07, 0x80);
- ds3000_writereg(state, 0x07, 0x00);
- /* ds3000 build-in uC reset */
+
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ if(state->cur_type == SYS_DVBS2) {
+ target_mclk = 144000;
+ } else {
+ target_mclk = 96000;
+ }
+
+ ds3000_writereg(state, 0x06, 0xe0);
+ _mt_fe_dmd_ds3k_select_mclk(state);
+ _mt_fe_dmd_ds3k_set_mclk(state, target_mclk);
+ ds3000_writereg(state, 0x06, 0x00);
+ msleep(10);
+
+ }
+
+ offset_khz = set_freq_ts2022(state) + 500;
+
+ dprintk("%s---cfg->output_mode----->>%d\n", __func__, cfg->output_mode);
+ //demod
ds3000_writereg(state, 0xb2, 0x01);
- /* ds3000 software reset */
- ds3000_writereg(state, 0x00, 0x01);
+ if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B)) {
+ ds3000_writereg(state, 0x00, 0x01);
+ }
+ value = ds3000_readreg(state, 0x08);
switch (c->delivery_system) {
case SYS_DVBS:
/* initialise the demod in DVB-S mode */
- for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
- ds3000_writereg(state,
- ds3000_dvbs_init_tab[i],
- ds3000_dvbs_init_tab[i + 1]);
- value = ds3000_readreg(state, 0xfe);
- value &= 0xc0;
- value |= 0x1b;
- ds3000_writereg(state, 0xfe, value);
+ value &= ~0x04;
+ ds3000_writereg(state, 0x08, value);
+ if(state->chip_ID == FeDmdId_DS300X) {
+ for(i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
+ ds3000_writereg(state, ds3000_dvbs_init_tab[i], ds3000_dvbs_init_tab[i + 1]);
+ } else if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B)) {
+ for (i = 0; i < sizeof(ds310x_dvbs_init_tab); i += 2)
+ ds3000_writereg(state, ds310x_dvbs_init_tab[i], ds310x_dvbs_init_tab[i + 1]);
+ }
+
+ if(cfg->output_mode == MtFeTsOutMode_Common) {
+ ts_clk = 6000; //8000;
+ } else if(cfg->output_mode == MtFeTsOutMode_Parallel) {
+ ts_clk = 24000;
+ } else {
+ ts_clk = 0;
+ }
+
+ target_mclk = 96000;
+ if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B)) {
+ value = ds3000_readreg(state, 0x4d);
+ value &= ~0x02;
+ ds3000_writereg(state, 0x4d, value);
+ value = ds3000_readreg(state, 0x30);
+ value &= ~0x10;
+ ds3000_writereg(state, 0x30, value);
+ }
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ // S mode, disable 192M LDPC clock, Reg. 29H bit4 = 1
+ value = ds3000_readreg(state, 0x29);
+ value |= 0x10;
+ ds3000_writereg(state, 0x29, value);
+ }
+
break;
case SYS_DVBS2:
/* initialise the demod in DVB-S2 mode */
- for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
- ds3000_writereg(state,
- ds3000_dvbs2_init_tab[i],
- ds3000_dvbs2_init_tab[i + 1]);
- if (c->symbol_rate >= 30000000)
- ds3000_writereg(state, 0xfe, 0x54);
- else
- ds3000_writereg(state, 0xfe, 0x98);
+ value |= 0x04;
+ ds3000_writereg(state, 0x08, value);
+ if(state->chip_ID == FeDmdId_DS300X)
+ {
+ for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
+ ds3000_writereg(state, ds3000_dvbs2_init_tab[i], ds3000_dvbs2_init_tab[i + 1]);
+ } else if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B)) {
+ for (i = 0; i < sizeof(ds310x_dvbs2_init_tab); i += 2)
+ ds3000_writereg(state, ds310x_dvbs2_init_tab[i], ds310x_dvbs2_init_tab[i + 1]);
+ }
+ //ts_clk = 18000;//zf8471;
+
+ if(cfg->output_mode == MtFeTsOutMode_Common) {
+ ts_clk = 6000; //8471;
+ } else if(cfg->output_mode == MtFeTsOutMode_Parallel) {
+ ts_clk = 24000;
+ } else {
+ ts_clk = 0;
+ }
+
+ if(state->chip_ID == FeDmdId_DS300X) {
+ target_mclk = 144000;
+ } else if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B)) {
+ value = ds3000_readreg(state, 0x4d);
+ value &= ~0x02;
+ ds3000_writereg(state, 0x4d, value);
+ value = ds3000_readreg(state, 0x30);
+ value &= ~0x10;
+ ds3000_writereg(state, 0x30, value);
+ if((cfg->output_mode == MtFeTsOutMode_Parallel) || (cfg->output_mode == MtFeTsOutMode_Common)) {
+ if(c->symbol_rate > 18000000) {
+ target_mclk = 144000;
+ } else {
+ target_mclk = 96000;
+ }
+ } else {
+#if (MT_FE_TS_CLOCK_AUTO_SET_FOR_SERIAL_MODE != 0)
+ if(c->symbol_rate > 18000000) {
+ target_mclk = 144000;
+ } else {
+ target_mclk = 96000;
+ }
+#else
+ target_mclk = MT_FE_MCLK_KHZ_SERIAL_S2;
+#endif
+ }
+ }
+
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ // S2 mode, enable 192M LDPC clock, Reg. 29H bit4 = 0
+ value = ds3000_readreg(state, 0x29);
+ value &= ~0x10;
+ ds3000_writereg(state, 0x29, value);
+ }
+
+ if(c->symbol_rate <= 5000000)
+ {
+ ds3000_writereg(state, 0xc0, 0x04);
+ ds3000_writereg(state, 0x8a, 0x09);
+ ds3000_writereg(state, 0x8b, 0x22);
+ ds3000_writereg(state, 0x8c, 0x88);
+ }
+
break;
default:
- return -EINVAL;
+ return 1;
}
- /* enable 27MHz clock output */
- ds3000_writereg(state, 0x29, 0x80);
- /* enable ac coupling */
- ds3000_writereg(state, 0x25, 0x8a);
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ value = ds3000_readreg(state, 0x9d);
+ value |= 0x08;
+ ds3000_writereg(state, 0x9d, value);
- if ((c->symbol_rate < ds3000_ops.info.symbol_rate_min) ||
- (c->symbol_rate > ds3000_ops.info.symbol_rate_max)) {
- dprintk("%s() symbol_rate %u out of range (%u ... %u)\n",
- __func__, c->symbol_rate,
- ds3000_ops.info.symbol_rate_min,
- ds3000_ops.info.symbol_rate_max);
- return -EINVAL;
+ tmp1 = ds3000_dt_read(state, 0x15);
+ tmp2 = ds3000_dt_read(state, 0x16);
+
+ if(c->symbol_rate > 45000000) {
+ tmp1 &= ~0x03;
+ tmp1 |= 0x02;
+ tmp1 |= ((147 - 32) >> 8) & 0x01;
+ tmp2 = (147 - 32) & 0xFF;
+
+ state->mclk_khz = 110250;
+ } else {
+ tmp1 &= ~0x03;
+ tmp1 |= ((128 - 32) >> 8) & 0x01;
+ tmp2 = (128 - 32) & 0xFF;
+
+ state->mclk_khz = 96000;
+ }
+ ds3000_dt_write(state, 0x15, tmp1);
+ ds3000_dt_write(state, 0x16, tmp2);
+
+ value = ds3000_readreg(state, 0x30);
+ value &= ~0x80;
+ ds3000_writereg(state, 0x30, value);
}
- /* enhance symbol rate performance */
- if ((c->symbol_rate / 1000) <= 5000) {
- value = 29777 / (c->symbol_rate / 1000) + 1;
- if (value % 2 != 0)
- value++;
- ds3000_writereg(state, 0xc3, 0x0d);
- ds3000_writereg(state, 0xc8, value);
- ds3000_writereg(state, 0xc4, 0x10);
- ds3000_writereg(state, 0xc7, 0x0e);
- } else if ((c->symbol_rate / 1000) <= 10000) {
- value = 92166 / (c->symbol_rate / 1000) + 1;
- if (value % 2 != 0)
- value++;
- ds3000_writereg(state, 0xc3, 0x07);
- ds3000_writereg(state, 0xc8, value);
- ds3000_writereg(state, 0xc4, 0x09);
- ds3000_writereg(state, 0xc7, 0x12);
- } else if ((c->symbol_rate / 1000) <= 20000) {
- value = 64516 / (c->symbol_rate / 1000) + 1;
- ds3000_writereg(state, 0xc3, value);
- ds3000_writereg(state, 0xc8, 0x0e);
- ds3000_writereg(state, 0xc4, 0x07);
- ds3000_writereg(state, 0xc7, 0x18);
+ if(ts_clk != 0) {
+ divide_ratio = (target_mclk + ts_clk - 1) / ts_clk;
+
+ if(divide_ratio > 128)
+ divide_ratio = 128;
+
+ if(divide_ratio < 2)
+ divide_ratio = 2;
+
+ tmp1 = (u8)(divide_ratio / 2);
+ tmp2 = (u8)(divide_ratio / 2);
+
+ if((divide_ratio % 2) != 0)
+ tmp2 += 1;
} else {
- value = 129032 / (c->symbol_rate / 1000) + 1;
- ds3000_writereg(state, 0xc3, value);
- ds3000_writereg(state, 0xc8, 0x0a);
- ds3000_writereg(state, 0xc4, 0x05);
- ds3000_writereg(state, 0xc7, 0x24);
+ divide_ratio = 0;
+ tmp1 = 0;
+ tmp2 = 0;
+ }
+
+ ds3000_setTSdiv(state, c->delivery_system, tmp1, tmp2);
+ _mt_fe_dmd_ds3k_set_mclk(state, target_mclk);
+
+ value = ds3000_readreg(state, 0xfd);
+ tmp = ds3000_readreg(state, 0xca);
+ tmp &= 0xFE;
+ tmp |= (value >> 3) & 0x01;
+ ds3000_writereg(state, 0xca, tmp);
+
+ ds3000_writereg(state, 0x33, 0x99);
+
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ tmp = ds3000_readreg(state, 0xC9);
+ tmp |= 0x08;
+ ds3000_writereg(state, 0xC9, tmp);
+ }
+
+ /* enhance symbol rate performance */
+ if(c->symbol_rate <= 3000000)
+ {
+ ds3000_writereg(state, 0xc3, 0x08); // 8 * 32 * 100 / 64 = 400
+ ds3000_writereg(state, 0xc8, 0x20);
+ ds3000_writereg(state, 0xc4, 0x08); // 8 * 0 * 100 / 128 = 0
+ ds3000_writereg(state, 0xc7, 0x00);
+ }
+ else if(c->symbol_rate <= 10000000)
+ {
+ ds3000_writereg(state, 0xc3, 0x08); // 8 * 16 * 100 / 64 = 200
+ ds3000_writereg(state, 0xc8, 0x10);
+ ds3000_writereg(state, 0xc4, 0x08); // 8 * 0 * 100 / 128 = 0
+ ds3000_writereg(state, 0xc7, 0x00);
+ }
+ else
+ {
+ ds3000_writereg(state, 0xc3, 0x08); // 8 * 6 * 100 / 64 = 75
+ ds3000_writereg(state, 0xc8, 0x06);
+ ds3000_writereg(state, 0xc4, 0x08); // 8 * 0 * 100 / 128 = 0
+ ds3000_writereg(state, 0xc7, 0x00);
}
/* normalized symbol rate rounded to the closest integer */
- value = (((c->symbol_rate / 1000) << 16) +
- (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
- ds3000_writereg(state, 0x61, value & 0x00ff);
- ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
- /* co-channel interference cancellation disabled */
- ds3000_writereg(state, 0x56, 0x00);
+ dprintk("%s----state->mclk_khz----->>%d\n", __func__, state->mclk_khz);
+ tmp = (u32)((((c->symbol_rate / 1000) << 15) + (state->mclk_khz / 4)) / (state->mclk_khz / 2));
+ ds3000_writereg(state, 0x61, tmp & 0x00ff);
+ ds3000_writereg(state, 0x62, (tmp & 0xff00) >> 8);
+
+ /* co-channel interference cancellation disabled */
+ value = ds3000_readreg(state, 0x56);
+ value &= ~0x01;
+ ds3000_writereg(state, 0x56, value);
/* equalizer disabled */
- ds3000_writereg(state, 0x76, 0x00);
-
- /*ds3000_writereg(state, 0x08, 0x03);
- ds3000_writereg(state, 0xfd, 0x22);
- ds3000_writereg(state, 0x08, 0x07);
- ds3000_writereg(state, 0xfd, 0x42);
- ds3000_writereg(state, 0x08, 0x07);*/
-
- if (state->config->ci_mode) {
- switch (c->delivery_system) {
- case SYS_DVBS:
- default:
- ds3000_writereg(state, 0xfd, 0x80);
- break;
- case SYS_DVBS2:
- ds3000_writereg(state, 0xfd, 0x01);
- break;
- }
+ value = ds3000_readreg(state, 0x76);
+ value &= ~0x80;
+ ds3000_writereg(state, 0x76, value);
+
+ //offset
+ if ((c->symbol_rate / 1000) < 5000)
+ offset_khz += 3000;
+ ds3000_set_carrier_offset(fe, offset_khz);
+
+ if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || state->chip_ID == FeDmdId_DS3103B) {
+ /* ds3000 out of software reset */
+ ds3000_writereg(state, 0x00, 0x00);
}
-
- /* ds3000 out of software reset */
- ds3000_writereg(state, 0x00, 0x00);
/* start ds3000 build-in uC */
ds3000_writereg(state, 0xb2, 0x00);
- if (fe->ops.tuner_ops.get_frequency) {
- fe->ops.tuner_ops.get_frequency(fe, &frequency);
- offset_khz = frequency - c->frequency;
- ds3000_set_carrier_offset(fe, offset_khz);
- }
for (i = 0; i < 30 ; i++) {
ds3000_read_status(fe, &status);
- if (status & FE_HAS_LOCK)
+ if (status && FE_HAS_LOCK)
break;
msleep(10);
@@ -1062,12 +2500,7 @@ static int ds3000_tune(struct dvb_frontend *fe,
static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
{
- struct ds3000_state *state = fe->demodulator_priv;
-
- if (state->config->set_lock_led)
- state->config->set_lock_led(fe, 0);
-
- dprintk("%s()\n", __func__);
+ //dprintk("%s()\n", __func__);
return DVBFE_ALGO_HW;
}
@@ -1079,12 +2512,114 @@ static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
static int ds3000_initfe(struct dvb_frontend *fe)
{
struct ds3000_state *state = fe->demodulator_priv;
+ struct ds3000_config *cfg = state->config;
int ret;
+ u8 buf;
+ u8 val_08;
+
+ state->mclk_khz = DS3000_SAMPLE_RATE;
dprintk("%s()\n", __func__);
/* hard reset */
+ if(state->chip_ID==FeDmdId_DS300X)
+ {
+ buf = ds3000_readreg(state, 0xb2);
+ if(buf == 0x01)
+ {
+ ds3000_writereg(state, 0x05, 0x00);
+ ds3000_writereg(state, 0xb2, 0x00);
+ }
+ }
+ else if ((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B))
+ {
+ buf = ds3000_readreg(state, 0xb2);
+ if(buf == 0x01)
+ {
+ ds3000_writereg(state, 0x00, 0x00);
+ ds3000_writereg(state, 0xb2, 0x00);
+ }
+ }
+ else
+ {
+ printk(KERN_ERR "%s: unknow demod version\n", __func__);
+ return -1; //Error, maybe other tuner ICs,please do action at top level application
+ }
+ ds3000_writereg(state, 0x07, 0x80);
+ ds3000_writereg(state, 0x07, 0x00);
+ ds3000_writereg(state, 0xb2, 0x00);
+ msleep(1);
ds3000_writereg(state, 0x08, 0x01 | ds3000_readreg(state, 0x08));
+
msleep(1);
+ if (state->chip_ID == FeDmdId_DS3103B) {
+ ds3000_writereg(state, 0x11, 0x01 | ds3000_readreg(state, 0x11));
+ }
+
+ //check tuner version
+ // Wake Up the tuner
+ buf = ds3000_tuner_readreg(state, 0x00);
+ buf &= 0x03;
+ if(buf == 0x00)
+ {
+ ds3000_tuner_writereg(state, 0x00, 0x01);
+ msleep(2);
+ }
+ ds3000_tuner_writereg(state, 0x00, 0x03);
+ msleep(2);
+
+ //Check the tuner version
+
+ buf = ds3000_tuner_readreg(state, 0x00);
+
+ if((buf == 0x01) || (buf == 0x41) || (buf == 0x81))
+ {
+ dprintk("FIND TUNER M88TS2020"); //A0 or A4 or A5
+ /* TS2020 init */
+ state->tuner_ID = TUNER_M88TS2020;
+ ds3000_tuner_writereg(state, 0x62, 0xfd);
+ ds3000_tuner_writereg(state, 0x42, 0x63);
+ ds3000_tuner_writereg(state, 0x07, 0x02);
+ ds3000_tuner_writereg(state, 0x08, 0x01);
+ }
+ else if((buf == 0xc3)|| (buf == 0x83) || (buf == 0xc1)) //yh add c1
+ {
+ dprintk("FIND TUNER_M88TS2022"); //C0 or C0A
+ /* TS2022 init */
+ state->tuner_ID = TUNER_M88TS2022;
+
+ ds3000_tuner_writereg(state, 0x62, 0xec);
+ msleep(2);
+ ds3000_tuner_writereg(state, 0x42, 0x6c);
+ msleep(2);
+
+ ds3000_tuner_writereg(state, 0x7d, 0x9d);
+ ds3000_tuner_writereg(state, 0x7c, 0x9a);
+ ds3000_tuner_writereg(state, 0x7a, 0x76);
+
+ ds3000_tuner_writereg(state, 0x3b, 0x01);
+ ds3000_tuner_writereg(state, 0x63, 0x88);
+
+ ds3000_tuner_writereg(state, 0x61, 0x85);
+ ds3000_tuner_writereg(state, 0x22, 0x30);
+ ds3000_tuner_writereg(state, 0x30, 0x40);
+ ds3000_tuner_writereg(state, 0x20, 0x23);
+ ds3000_tuner_writereg(state, 0x24, 0x02);
+ ds3000_tuner_writereg(state, 0x12, 0xa0);
+ }
+ else
+ {
+ state->tuner_ID = TUNER_UNKNOW;
+ printk(KERN_ERR "%s: Unable check tuner version\n", __func__);
+ return -1; //Error, maybe other tuner ICs,please do action at top level application
+ }
+
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ ds3000_dt_write(state, 0x21, 0x92);
+ ds3000_dt_write(state, 0x15, 0x6C);
+ ds3000_dt_write(state, 0x17, 0xC1);
+ ds3000_dt_write(state, 0x17, 0x81);
+ }
/* Load the firmware if required */
ret = ds3000_firmware_ondemand(fe);
@@ -1092,14 +2627,213 @@ static int ds3000_initfe(struct dvb_frontend *fe)
printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
return ret;
}
+ //TS mode
+ val_08 = ds3000_readreg(state, 0x08);
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ buf = ds3000_readreg(state, 0x29);
+ buf &= ~0x01;
+ ds3000_writereg(state, 0x29, buf);
+ } else {
+ buf = ds3000_readreg(state, 0x27);
+ buf &= ~0x01;
+ ds3000_writereg(state, 0x27, buf);
+ }
+
+ //dvbs
+ buf = val_08 & (~0x04) ;
+ ds3000_writereg(state, 0x08, buf);
+ ds3000_setTSdiv(state, SYS_DVBS, 6, 6);
+
+
+//lxg if(state->chip_ID == FeDmdId_DS300X) {
+ buf = ds3000_readreg(state, 0xfd);
+ if(cfg->output_mode == MtFeTsOutMode_Parallel) {
+ buf &= ~0x80;
+ buf &= ~0x40;
+ } else if(cfg->output_mode == MtFeTsOutMode_Serial) {
+ buf &= ~0x80;
+ buf |= 0x40;
+ } else {
+ buf |= 0x80;
+ buf &= ~0x40;
+ }
+
+ if(cfg->ci_mode)
+ buf |= 0x20;
+ else
+ buf &= ~0x20;
+ buf &= ~0x1f;
+ ds3000_writereg(state, 0xfd, buf);
+// }
+
+ //S2
+ buf = val_08 | 0x04 ;
+ ds3000_writereg(state, 0x08, buf);
+// if(state->chip_ID == FeDmdId_DS3103B)
+// ds3000_setTSdiv(state, SYS_DVBS2, 8, 8);
+// else
+ ds3000_setTSdiv(state, SYS_DVBS2, 8, 9);
+ buf = ds3000_readreg(state, 0xfd);
+ if(cfg->output_mode == MtFeTsOutMode_Parallel) {
+ buf &= ~0x01;
+ buf &= ~0x04;
+ } else if(cfg->output_mode == MtFeTsOutMode_Serial) {
+ buf &= ~0x01;
+ buf |= 0x04;
+ } else {
+ buf |= 0x01;
+ buf &= ~0x04;
+ }
+ if(cfg->ci_mode) {
+ buf &= ~0xba;
+ buf |= 0x40;
+ } else {
+ buf &= ~0xb8;
+ buf &= ~0x42; //lxg buf |= 0x42;
+ }
+ ds3000_writereg(state, 0xfd, buf);
+
+ ds3000_writereg(state, 0x08, val_08);
+
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ u8 val = 0, tmp;
+ if(cfg->output_mode != MtFeTsOutMode_Serial) {
+ tmp = MT_FE_ENHANCE_TS_PIN_LEVEL_PARALLEL_CI;
+
+ val |= tmp & 0x03;
+ val |= (tmp << 2) & 0x0C;
+ val |= (tmp << 4) & 0x30;
+ val |= (tmp << 6) & 0xC0;
+ } else {
+ tmp = MT_FE_ENHANCE_TS_PIN_LEVEL_SERIAL;
+
+ val |= tmp & 0x03;
+ val |= (tmp << 2) & 0x0C;
+ val |= (tmp << 4) & 0x30;
+ val |= (tmp << 6) & 0xC0;
+ }
+ ds3000_writereg(state, 0x20, val);
+ } else {
+ buf = ds3000_readreg(state, 0x27);
+ buf |= 0x01;
+ if(((MT_FE_ENHANCE_TS_PIN_LEVEL_PARALLEL_CI != 0) && (cfg->output_mode != MtFeTsOutMode_Serial))
+ || ((MT_FE_ENHANCE_TS_PIN_LEVEL_SERIAL != 0) && (cfg->output_mode == MtFeTsOutMode_Serial))) {
+ buf &= ~0x10;
+ } else {
+ buf |= 0x10;
+ }
+ ds3000_writereg(state, 0x27, buf);
+ }
+
+ buf = ds3000_readreg(state, 0x29);
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ if(MT_FE_TS_PIN_ORDER_D0_D7 != 0) {
+ buf |= 0x20;
+ } else {
+ buf &= ~0x20;
+ }
+
+ buf |= 0x01;
+ } else {
+ if((MT_FE_TS_PIN_ORDER_D0_D7 != 0) && (cfg->output_mode == MtFeTsOutMode_Serial)) {
+ buf |= 0x20;
+ } else {
+ buf &= ~0x20;
+ }
+ }
+ ds3000_writereg(state, 0x29, buf);
+ // Ts mode end
+
+
+ if(state->chip_ID != FeDmdId_DS3103B) {
+ buf = ds3000_readreg(state, 0x29);
+#if MT_FE_ENABLE_27MHZ_CLOCK_OUT
+ buf &= ~0x80;
+#if MT_FE_ENABLE_13_P_5_MHZ_CLOCK_OUT
+ buf |= 0x10;
+#else
+ buf &= ~0x10;
+#endif
+#else
+ buf |= 0x80;
+#endif
+ ds3000_writereg(state, 0x29, buf);
+ } else {
+ buf = ds3000_readreg(state, 0x11);
+#if (MT_FE_ENABLE_27MHZ_CLOCK_OUT && (ENABLE_CLKOUT_AS_GPIO == 0))
+ buf &= ~0x08;
+#elif((MT_FE_ENABLE_27MHZ_CLOCK_OUT == 0) && ENABLE_CLKOUT_AS_GPIO)
+ buf |= 0x08;
+#if GPIO_CLKOUT_AS_INPUT
+ buf |= 0x04;
+#else
+ buf &= ~0x04;
+#endif
+#endif
+
+#if ENABLE_ITLOCK_AS_GPIO
+ buf |= 0x80;
+#if GPIO_ITLOCK_AS_INPUT
+ buf |= 0x40;
+#else
+ buf &= ~0x40;
+#endif
+#else
+ buf &= ~0x80;
+#endif
+ ds3000_writereg(state, 0x11, buf);
+ }
+
+#if MT_FE_ENABLE_AC_COUPLING
+ buf = ds3000_readreg(state, 0x25);
+ buf |= 0x08;
+ ds3000_writereg(state, 0x25, buf);
+#endif
+
+ //
+ if((state->chip_ID == FeDmdId_DS3002B) || (state->chip_ID == FeDmdId_DS3103)
+ || (state->chip_ID == FeDmdId_DS3103B)) {
+ buf = ds3000_readreg(state, 0x4d);
+ buf &= ~0x02;
+ ds3000_writereg(state, 0x4d, buf);
+ buf = ds3000_readreg(state, 0x30);
+ buf &= ~0x10;
+ ds3000_writereg(state, 0x30, buf);
+
+ ds3000_writereg(state, 0xf1, 0x01);
+ if(state->chip_ID == FeDmdId_DS3103B) {
+ buf = ds3000_readreg(state, 0x29);
+ if(LNB_DISEQC_OUT_ONLY_OUTPUT == 1) {
+ buf |= 0x40;
+ } else {
+ buf &= ~0x40;
+ }
+ ds3000_writereg(state, 0x29, buf);
+
+ buf = ds3000_readreg(state, 0x9d);
+ buf |= 0x08;
+ ds3000_writereg(state, 0x9d, buf);
+ }
+ }
+ return 0;
+}
+/* Put device to sleep */
+static int ds3000_sleep(struct dvb_frontend *fe)
+{
+ struct ds3000_state *state = fe->demodulator_priv;
+
+ if (state->config->set_lock_led)
+ state->config->set_lock_led(fe, 0);
+
+ dprintk("%s()\n", __func__);
return 0;
}
-static const struct dvb_frontend_ops ds3000_ops = {
+static struct dvb_frontend_ops ds3000_ops = {
.delsys = { SYS_DVBS, SYS_DVBS2 },
.info = {
- .name = "Montage Technology DS3000",
+ .name = "Montage Technology DS3000/TS2020",
.frequency_min = 950000,
.frequency_max = 2150000,
.frequency_stepsize = 1011, /* kHz for QPSK frontends */
@@ -1117,7 +2851,7 @@ static const struct dvb_frontend_ops ds3000_ops = {
.release = ds3000_release,
.init = ds3000_initfe,
- .i2c_gate_ctrl = ds3000_i2c_gate_ctrl,
+ .sleep = ds3000_sleep,
.read_status = ds3000_read_status,
.read_ber = ds3000_read_ber,
.read_signal_strength = ds3000_read_signal_strength,
@@ -1129,6 +2863,8 @@ static const struct dvb_frontend_ops ds3000_ops = {
.diseqc_send_burst = ds3000_diseqc_send_burst,
.get_frontend_algo = ds3000_get_algo,
+ //.set_property = ds3000_set_property,
+ //.get_property = ds3000_get_property,
.set_frontend = ds3000_set_frontend,
.tune = ds3000_tune,
};
@@ -1136,7 +2872,8 @@ static const struct dvb_frontend_ops ds3000_ops = {
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-MODULE_DESCRIPTION("DVB Frontend module for Montage Technology DS3000 hardware");
-MODULE_AUTHOR("Konstantin Dimitrov <kosio.dimitrov@gmail.com>");
+MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
+ "DS3000/TS2020 hardware");
+MODULE_AUTHOR("Konstantin Dimitrov");
MODULE_LICENSE("GPL");
-MODULE_FIRMWARE(DS3000_DEFAULT_FIRMWARE);
+
diff --git a/drivers/media/dvb-frontends/ds3000.h b/drivers/media/dvb-frontends/ds3000.h
index 82e8c253..bcf1b368 100644
--- a/drivers/media/dvb-frontends/ds3000.h
+++ b/drivers/media/dvb-frontends/ds3000.h
@@ -24,10 +24,82 @@
#include <linux/dvb/frontend.h>
+/* AC coupling control*/
+#define MT_FE_ENABLE_AC_COUPLING 1 /*1: AC coupling (recommended in reference design) 0: DC coupling*/
+
+#define MT_FE_MCLK_KHZ_SERIAL_S2 144000 //96000
+
+
+#define MT_FE_ENHANCE_TS_PIN_LEVEL_PARALLEL_CI 0 // Parallel Mode or Common Interface Mode
+#define MT_FE_ENHANCE_TS_PIN_LEVEL_SERIAL 1 // Serial Mode
+
+/* CLOCK OUTPUT TO DECODER*/
+#define MT_FE_ENABLE_27MHZ_CLOCK_OUT 0
+#define MT_FE_ENABLE_13_P_5_MHZ_CLOCK_OUT 0
+
+/******************** LNB and DISEQC DEFINES ************************/
+/* Maybe user need change the defines according to reference design */
+#define LNB_ENABLE_WHEN_LNB_EN_HIGH 0
+#define LNB_13V_WHEN_VSEL_HIGH 1
+#define LNB_VSEL_STANDBY_HIGH 1
+#define LNB_DISEQC_OUT_FORCE_HIGH 0
+#define LNB_DISEQC_OUT_ONLY_OUTPUT 0
+
+/******************** GPIO DEFINES **************************************/
+#define ENABLE_OLF_AS_GPIO 0
+#define GPIO_OLF_AS_INPUT 0
+#define ENABLE_MERR_AS_GPIO 0
+#define GPIO_MERR_AS_INPUT 0
+#define ENABLE_ITLOCK_AS_GPIO 0
+#define GPIO_ITLOCK_AS_INPUT 0
+#define ENABLE_CLKOUT_AS_GPIO 0
+#define GPIO_CLKOUT_AS_INPUT 0
+
+
+#define MtFeTsOutMode_Serial 1
+#define MtFeTsOutMode_Parallel 2
+#define MtFeTsOutMode_Common 3
+
+#define MT_FE_TS_OUTPUT_MODE MtFeTsOutMode_Common
+
+
+
+#define MT_FE_TS_PIN_ORDER_D0_D7 0 // 0: D0, 1: D7
+
+#define MT_FE_TS_CLOCK_AUTO_SET_FOR_SERIAL_MODE 1
+
+#if(MT_FE_TS_OUTPUT_MODE == MtFeTsOutMode_Parallel)
+/***************************************************************
+In parallel mode, user can select the max clock out frequency
+according to the decoder's max clock frequency.
+
+Four Options:
+MtFeTSOut_Max_Clock_12_MHz; MtFeTSOut_Max_Clock_16_MHz
+MtFeTSOut_Max_Clock_19_p_2_MHz; MtFeTSOut_Max_Clock_24_MHz;
+
+Default setting is 24MHz.
+***************************************************************/
+#define MtFeTSOut_Max_Clock_12_MHz 0
+#define MtFeTSOut_Max_Clock_16_MHz 0
+#define MtFeTSOut_Max_Clock_19_p_2_MHz 0
+#define MtFeTSOut_Max_Clock_24_MHz 0
+#define MT_FE_TS_CLOCK_AUTO_SET_FOR_CI_MODE 1
+
+#elif (MT_FE_TS_OUTPUT_MODE == MtFeTsOutMode_Common)
+/*********************** TS Clock Auto Set ************************
+** MT_FE_TS_CLOCK_AUTO_SET_FOR_CI_MODE == 1 Automatically set TS clock
+**
+** TS clock will be automatically set just according to the
+** modulation mode/code rate/symbol rate after TP locked.
+*********************************************************************/
+#define MT_FE_TS_CLOCK_AUTO_SET_FOR_CI_MODE 1
+#endif
+
struct ds3000_config {
/* the demodulator's i2c address */
u8 demod_address;
u8 ci_mode;
+ u8 output_mode;
/* Set device param to start dma */
int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
/* Hook for Lock LED */
@@ -35,11 +107,11 @@ struct ds3000_config {
};
#if IS_REACHABLE(CONFIG_DVB_DS3000)
-extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+extern struct dvb_frontend *ds3000_attach(struct ds3000_config *config,
struct i2c_adapter *i2c);
#else
static inline
-struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
+struct dvb_frontend *ds3000_attach(struct ds3000_config *config,
struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
diff --git a/drivers/media/dvb-frontends/ds3000_firmware.h b/drivers/media/dvb-frontends/ds3000_firmware.h
new file mode 100755
index 00000000..dede59ad
--- /dev/null
+++ b/drivers/media/dvb-frontends/ds3000_firmware.h
@@ -0,0 +1,8203 @@
+
+const unsigned char ds300x_firmware[] = {
+ 0x83, 0x01, /* 0 */
+ 0x00, 0x30, /* 1 */
+ 0x8a, 0x00, /* 2 */
+ 0x04, 0x28, /* 3 */
+ 0x22, 0x30, /* 4 */
+ 0x84, 0x00, /* 5 */
+ 0x57, 0x30, /* 6 */
+ 0x12, 0x20, /* 7 */
+ 0x20, 0x30, /* 8 */
+ 0x84, 0x00, /* 9 */
+ 0x22, 0x30, /* 10 */
+ 0x12, 0x20, /* 11 */
+ 0x83, 0x01, /* 12 */
+ 0x8a, 0x15, /* 13 */
+ 0x60, 0x2c, /* 14 */
+ 0x04, 0x06, /* 15 */
+ 0x80, 0x01, /* 16 */
+ 0x84, 0x0a, /* 17 */
+ 0x04, 0x06, /* 18 */
+ 0x03, 0x1d, /* 19 */
+ 0x0f, 0x28, /* 20 */
+ 0x00, 0x34, /* 21 */
+ 0x00, 0x00, /* 22 */
+ 0x00, 0x00, /* 23 */
+ 0x00, 0x00, /* 24 */
+ 0xeb, 0x30, /* 25 */
+ 0x83, 0x01, /* 26 */
+ 0x8c, 0x00, /* 27 */
+ 0xe2, 0x3b, /* 28 */
+ 0x00, 0x00, /* 29 */
+ 0x11, 0x08, /* 30 */
+ 0x2f, 0x06, /* 31 */
+ 0x03, 0x1d, /* 32 */
+ 0x26, 0x28, /* 33 */
+ 0x10, 0x08, /* 34 */
+ 0x2e, 0x06, /* 35 */
+ 0x03, 0x19, /* 36 */
+ 0x08, 0x00, /* 37 */
+ 0x11, 0x08, /* 38 */
+ 0xaf, 0x00, /* 39 */
+ 0x10, 0x08, /* 40 */
+ 0xae, 0x00, /* 41 */
+ 0x3d, 0x08, /* 42 */
+ 0x94, 0x00, /* 43 */
+ 0x3e, 0x08, /* 44 */
+ 0x95, 0x00, /* 45 */
+ 0x00, 0x00, /* 46 */
+ 0x6c, 0x3b, /* 47 */
+ 0x00, 0x00, /* 48 */
+ 0x15, 0x08, /* 49 */
+ 0x94, 0x00, /* 50 */
+ 0x16, 0x08, /* 51 */
+ 0x95, 0x00, /* 52 */
+ 0x17, 0x08, /* 53 */
+ 0x96, 0x00, /* 54 */
+ 0x97, 0x1f, /* 55 */
+ 0x3c, 0x28, /* 56 */
+ 0xff, 0x30, /* 57 */
+ 0x97, 0x00, /* 58 */
+ 0x3d, 0x28, /* 59 */
+ 0x97, 0x01, /* 60 */
+ 0x25, 0x08, /* 61 */
+ 0x90, 0x00, /* 62 */
+ 0x26, 0x08, /* 63 */
+ 0x91, 0x00, /* 64 */
+ 0x27, 0x08, /* 65 */
+ 0x92, 0x00, /* 66 */
+ 0x28, 0x08, /* 67 */
+ 0x93, 0x00, /* 68 */
+ 0x00, 0x00, /* 69 */
+ 0x72, 0x3b, /* 70 */
+ 0x00, 0x00, /* 71 */
+ 0x14, 0x08, /* 72 */
+ 0xa5, 0x00, /* 73 */
+ 0x15, 0x08, /* 74 */
+ 0xa6, 0x00, /* 75 */
+ 0x16, 0x08, /* 76 */
+ 0xa7, 0x00, /* 77 */
+ 0x17, 0x08, /* 78 */
+ 0xa8, 0x00, /* 79 */
+ 0xdc, 0x30, /* 80 */
+ 0x8d, 0x00, /* 81 */
+ 0xfa, 0x3b, /* 82 */
+ 0x08, 0x00, /* 83 */
+ 0x26, 0x30, /* 84 */
+ 0x83, 0x01, /* 85 */
+ 0x9c, 0x00, /* 86 */
+ 0x9e, 0x01, /* 87 */
+ 0x28, 0x30, /* 88 */
+ 0x9c, 0x00, /* 89 */
+ 0x9e, 0x01, /* 90 */
+ 0x2a, 0x30, /* 91 */
+ 0x9c, 0x00, /* 92 */
+ 0x9e, 0x01, /* 93 */
+ 0x2e, 0x30, /* 94 */
+ 0x9c, 0x00, /* 95 */
+ 0x9e, 0x01, /* 96 */
+ 0x28, 0x30, /* 97 */
+ 0x9c, 0x00, /* 98 */
+ 0x1e, 0x14, /* 99 */
+ 0xff, 0x30, /* 100 */
+ 0xcf, 0x00, /* 101 */
+ 0x10, 0x30, /* 102 */
+ 0xd0, 0x00, /* 103 */
+ 0x4f, 0x08, /* 104 */
+ 0xd1, 0x00, /* 105 */
+ 0xd1, 0x0b, /* 106 */
+ 0x6a, 0x28, /* 107 */
+ 0xd0, 0x0b, /* 108 */
+ 0x68, 0x28, /* 109 */
+ 0x07, 0x30, /* 110 */
+ 0x9c, 0x00, /* 111 */
+ 0x00, 0x00, /* 112 */
+ 0x1d, 0x08, /* 113 */
+ 0xce, 0x00, /* 114 */
+ 0x4e, 0x18, /* 115 */
+ 0x7c, 0x28, /* 116 */
+ 0x24, 0x30, /* 117 */
+ 0x9c, 0x00, /* 118 */
+ 0x1e, 0x14, /* 119 */
+ 0x9e, 0x01, /* 120 */
+ 0x26, 0x30, /* 121 */
+ 0x9c, 0x00, /* 122 */
+ 0x1e, 0x14, /* 123 */
+ 0x10, 0x30, /* 124 */
+ 0xd0, 0x00, /* 125 */
+ 0x4f, 0x08, /* 126 */
+ 0xd1, 0x00, /* 127 */
+ 0xd1, 0x0b, /* 128 */
+ 0x80, 0x28, /* 129 */
+ 0xd0, 0x0b, /* 130 */
+ 0x7e, 0x28, /* 131 */
+ 0x2a, 0x30, /* 132 */
+ 0x9c, 0x00, /* 133 */
+ 0x1e, 0x14, /* 134 */
+ 0x2e, 0x30, /* 135 */
+ 0x9c, 0x00, /* 136 */
+ 0x1e, 0x14, /* 137 */
+ 0x08, 0x00, /* 138 */
+ 0x83, 0x01, /* 139 */
+ 0x4e, 0x08, /* 140 */
+ 0x90, 0x00, /* 141 */
+ 0x4f, 0x08, /* 142 */
+ 0x91, 0x00, /* 143 */
+ 0x50, 0x08, /* 144 */
+ 0x94, 0x00, /* 145 */
+ 0x51, 0x08, /* 146 */
+ 0x95, 0x00, /* 147 */
+ 0x00, 0x00, /* 148 */
+ 0x6c, 0x3b, /* 149 */
+ 0x00, 0x00, /* 150 */
+ 0x17, 0x08, /* 151 */
+ 0xd3, 0x00, /* 152 */
+ 0x16, 0x08, /* 153 */
+ 0xd2, 0x00, /* 154 */
+ 0x53, 0x08, /* 155 */
+ 0xf1, 0x00, /* 156 */
+ 0x52, 0x08, /* 157 */
+ 0xf0, 0x00, /* 158 */
+ 0x08, 0x00, /* 159 */
+ 0x83, 0x01, /* 160 */
+ 0xd2, 0x00, /* 161 */
+ 0x90, 0x01, /* 162 */
+ 0x91, 0x01, /* 163 */
+ 0x92, 0x01, /* 164 */
+ 0x93, 0x01, /* 165 */
+ 0x93, 0x16, /* 166 */
+ 0x52, 0x0a, /* 167 */
+ 0xf0, 0x00, /* 168 */
+ 0xac, 0x28, /* 169 */
+ 0x03, 0x10, /* 170 */
+ 0x93, 0x0c, /* 171 */
+ 0xf0, 0x0b, /* 172 */
+ 0xaa, 0x28, /* 173 */
+ 0x83, 0x12, /* 174 */
+ 0x03, 0x13, /* 175 */
+ 0x94, 0x01, /* 176 */
+ 0x95, 0x01, /* 177 */
+ 0x50, 0x08, /* 178 */
+ 0x96, 0x00, /* 179 */
+ 0x51, 0x08, /* 180 */
+ 0x97, 0x00, /* 181 */
+ 0xd4, 0x01, /* 182 */
+ 0xd5, 0x01, /* 183 */
+ 0x11, 0x30, /* 184 */
+ 0xd3, 0x00, /* 185 */
+ 0xb2, 0x3b, /* 186 */
+ 0x03, 0x10, /* 187 */
+ 0x97, 0x0c, /* 188 */
+ 0x96, 0x0c, /* 189 */
+ 0x95, 0x0c, /* 190 */
+ 0x94, 0x0c, /* 191 */
+ 0x03, 0x10, /* 192 */
+ 0xd4, 0x0d, /* 193 */
+ 0xd5, 0x0d, /* 194 */
+ 0x9b, 0x1f, /* 195 */
+ 0x17, 0x1b, /* 196 */
+ 0xcf, 0x28, /* 197 */
+ 0x18, 0x08, /* 198 */
+ 0x90, 0x00, /* 199 */
+ 0x19, 0x08, /* 200 */
+ 0x91, 0x00, /* 201 */
+ 0x1a, 0x08, /* 202 */
+ 0x92, 0x00, /* 203 */
+ 0x1b, 0x08, /* 204 */
+ 0x93, 0x00, /* 205 */
+ 0x54, 0x14, /* 206 */
+ 0xd3, 0x0b, /* 207 */
+ 0xba, 0x28, /* 208 */
+ 0x55, 0x08, /* 209 */
+ 0xf1, 0x00, /* 210 */
+ 0x54, 0x08, /* 211 */
+ 0xf0, 0x00, /* 212 */
+ 0x08, 0x00, /* 213 */
+ 0x83, 0x01, /* 214 */
+ 0xd1, 0x00, /* 215 */
+ 0x06, 0x30, /* 216 */
+ 0xd3, 0x00, /* 217 */
+ 0xd0, 0x08, /* 218 */
+ 0x03, 0x1d, /* 219 */
+ 0xdf, 0x28, /* 220 */
+ 0x04, 0x30, /* 221 */
+ 0xe0, 0x28, /* 222 */
+ 0x09, 0x30, /* 223 */
+ 0xd4, 0x00, /* 224 */
+ 0x05, 0x30, /* 225 */
+ 0xd2, 0x00, /* 226 */
+ 0xd4, 0x08, /* 227 */
+ 0x03, 0x1d, /* 228 */
+ 0xea, 0x28, /* 229 */
+ 0x5d, 0x30, /* 230 */
+ 0xd5, 0x00, /* 231 */
+ 0x74, 0x30, /* 232 */
+ 0x2c, 0x29, /* 233 */
+ 0x54, 0x0b, /* 234 */
+ 0xef, 0x28, /* 235 */
+ 0xd5, 0x01, /* 236 */
+ 0x64, 0x30, /* 237 */
+ 0x2c, 0x29, /* 238 */
+ 0x54, 0x08, /* 239 */
+ 0x02, 0x3a, /* 240 */
+ 0x03, 0x1d, /* 241 */
+ 0xf6, 0x28, /* 242 */
+ 0x55, 0x30, /* 243 */
+ 0xd5, 0x00, /* 244 */
+ 0x2c, 0x29, /* 245 */
+ 0x54, 0x08, /* 246 */
+ 0x03, 0x3a, /* 247 */
+ 0x03, 0x1d, /* 248 */
+ 0xfe, 0x28, /* 249 */
+ 0xb5, 0x30, /* 250 */
+ 0xd5, 0x00, /* 251 */
+ 0x47, 0x30, /* 252 */
+ 0x2c, 0x29, /* 253 */
+ 0x54, 0x08, /* 254 */
+ 0x04, 0x3a, /* 255 */
+ 0x03, 0x1d, /* 256 */
+ 0x06, 0x29, /* 257 */
+ 0xaa, 0x30, /* 258 */
+ 0xd5, 0x00, /* 259 */
+ 0x3c, 0x30, /* 260 */
+ 0x2c, 0x29, /* 261 */
+ 0x54, 0x08, /* 262 */
+ 0x05, 0x3a, /* 263 */
+ 0x03, 0x1d, /* 264 */
+ 0x0e, 0x29, /* 265 */
+ 0xab, 0x30, /* 266 */
+ 0xd5, 0x00, /* 267 */
+ 0x6a, 0x30, /* 268 */
+ 0x2c, 0x29, /* 269 */
+ 0x54, 0x08, /* 270 */
+ 0x06, 0x3a, /* 271 */
+ 0x03, 0x1d, /* 272 */
+ 0x16, 0x29, /* 273 */
+ 0x6e, 0x30, /* 274 */
+ 0xd5, 0x00, /* 275 */
+ 0x5b, 0x30, /* 276 */
+ 0x2c, 0x29, /* 277 */
+ 0x54, 0x08, /* 278 */
+ 0x07, 0x3a, /* 279 */
+ 0x03, 0x1d, /* 280 */
+ 0x1d, 0x29, /* 281 */
+ 0xd5, 0x01, /* 282 */
+ 0x50, 0x30, /* 283 */
+ 0x2c, 0x29, /* 284 */
+ 0x54, 0x08, /* 285 */
+ 0x08, 0x3a, /* 286 */
+ 0x03, 0x1d, /* 287 */
+ 0x25, 0x29, /* 288 */
+ 0xa4, 0x30, /* 289 */
+ 0xd5, 0x00, /* 290 */
+ 0x41, 0x30, /* 291 */
+ 0x2c, 0x29, /* 292 */
+ 0x54, 0x08, /* 293 */
+ 0x09, 0x3a, /* 294 */
+ 0x03, 0x1d, /* 295 */
+ 0x2d, 0x29, /* 296 */
+ 0xe4, 0x30, /* 297 */
+ 0xd5, 0x00, /* 298 */
+ 0x38, 0x30, /* 299 */
+ 0xd6, 0x00, /* 300 */
+ 0xd4, 0x03, /* 301 */
+ 0x51, 0x0a, /* 302 */
+ 0xf0, 0x00, /* 303 */
+ 0x34, 0x29, /* 304 */
+ 0x03, 0x10, /* 305 */
+ 0xd6, 0x0c, /* 306 */
+ 0xd5, 0x0c, /* 307 */
+ 0xf0, 0x0b, /* 308 */
+ 0x31, 0x29, /* 309 */
+ 0x83, 0x12, /* 310 */
+ 0x03, 0x13, /* 311 */
+ 0x3e, 0x08, /* 312 */
+ 0x56, 0x02, /* 313 */
+ 0x03, 0x1d, /* 314 */
+ 0x3e, 0x29, /* 315 */
+ 0x3d, 0x08, /* 316 */
+ 0x55, 0x02, /* 317 */
+ 0x03, 0x18, /* 318 */
+ 0x42, 0x29, /* 319 */
+ 0x52, 0x08, /* 320 */
+ 0xd3, 0x00, /* 321 */
+ 0xd2, 0x0b, /* 322 */
+ 0xe3, 0x28, /* 323 */
+ 0x50, 0x08, /* 324 */
+ 0xd3, 0x02, /* 325 */
+ 0x53, 0x08, /* 326 */
+ 0x08, 0x00, /* 327 */
+ 0x35, 0x30, /* 328 */
+ 0x83, 0x01, /* 329 */
+ 0x3e, 0x02, /* 330 */
+ 0x56, 0x30, /* 331 */
+ 0x03, 0x19, /* 332 */
+ 0x3d, 0x02, /* 333 */
+ 0x03, 0x1c, /* 334 */
+ 0x54, 0x29, /* 335 */
+ 0xd0, 0x01, /* 336 */
+ 0xaa, 0x01, /* 337 */
+ 0xaa, 0x0a, /* 338 */
+ 0x83, 0x29, /* 339 */
+ 0x1a, 0x30, /* 340 */
+ 0x3e, 0x02, /* 341 */
+ 0xab, 0x30, /* 342 */
+ 0x03, 0x19, /* 343 */
+ 0x3d, 0x02, /* 344 */
+ 0x03, 0x1c, /* 345 */
+ 0x5f, 0x29, /* 346 */
+ 0xd0, 0x01, /* 347 */
+ 0xd0, 0x0a, /* 348 */
+ 0x02, 0x30, /* 349 */
+ 0x82, 0x29, /* 350 */
+ 0x0d, 0x30, /* 351 */
+ 0x3e, 0x02, /* 352 */
+ 0x55, 0x30, /* 353 */
+ 0x03, 0x19, /* 354 */
+ 0x3d, 0x02, /* 355 */
+ 0x03, 0x1c, /* 356 */
+ 0x6a, 0x29, /* 357 */
+ 0x02, 0x30, /* 358 */
+ 0xd0, 0x00, /* 359 */
+ 0x04, 0x30, /* 360 */
+ 0x82, 0x29, /* 361 */
+ 0x06, 0x30, /* 362 */
+ 0x3e, 0x02, /* 363 */
+ 0xab, 0x30, /* 364 */
+ 0x03, 0x19, /* 365 */
+ 0x3d, 0x02, /* 366 */
+ 0x03, 0x30, /* 367 */
+ 0x03, 0x1c, /* 368 */
+ 0x75, 0x29, /* 369 */
+ 0xd0, 0x00, /* 370 */
+ 0x08, 0x30, /* 371 */
+ 0x82, 0x29, /* 372 */
+ 0x3e, 0x02, /* 373 */
+ 0x55, 0x30, /* 374 */
+ 0x03, 0x19, /* 375 */
+ 0x3d, 0x02, /* 376 */
+ 0x03, 0x1c, /* 377 */
+ 0x7f, 0x29, /* 378 */
+ 0x04, 0x30, /* 379 */
+ 0xd0, 0x00, /* 380 */
+ 0x10, 0x30, /* 381 */
+ 0x82, 0x29, /* 382 */
+ 0x05, 0x30, /* 383 */
+ 0xd0, 0x00, /* 384 */
+ 0x20, 0x30, /* 385 */
+ 0xaa, 0x00, /* 386 */
+ 0x50, 0x08, /* 387 */
+ 0x08, 0x00, /* 388 */
+ 0x83, 0x01, /* 389 */
+ 0xd2, 0x00, /* 390 */
+ 0x90, 0x00, /* 391 */
+ 0x91, 0x01, /* 392 */
+ 0x50, 0x08, /* 393 */
+ 0x94, 0x00, /* 394 */
+ 0x51, 0x08, /* 395 */
+ 0x95, 0x00, /* 396 */
+ 0x00, 0x00, /* 397 */
+ 0x6c, 0x3b, /* 398 */
+ 0x00, 0x00, /* 399 */
+ 0x16, 0x08, /* 400 */
+ 0xd4, 0x00, /* 401 */
+ 0x15, 0x08, /* 402 */
+ 0xd3, 0x00, /* 403 */
+ 0x54, 0x08, /* 404 */
+ 0xf1, 0x00, /* 405 */
+ 0x53, 0x08, /* 406 */
+ 0xf0, 0x00, /* 407 */
+ 0x08, 0x00, /* 408 */
+ 0x83, 0x01, /* 409 */
+ 0xd0, 0x00, /* 410 */
+ 0x8c, 0x00, /* 411 */
+ 0x00, 0x00, /* 412 */
+ 0xe0, 0x3b, /* 413 */
+ 0x00, 0x00, /* 414 */
+ 0x11, 0x08, /* 415 */
+ 0xd2, 0x00, /* 416 */
+ 0x10, 0x08, /* 417 */
+ 0xd1, 0x00, /* 418 */
+ 0x52, 0x08, /* 419 */
+ 0xf1, 0x00, /* 420 */
+ 0x51, 0x08, /* 421 */
+ 0xf0, 0x00, /* 422 */
+ 0x08, 0x00, /* 423 */
+ 0x83, 0x01, /* 424 */
+ 0xa1, 0x13, /* 425 */
+ 0xcc, 0x01, /* 426 */
+ 0xcd, 0x01, /* 427 */
+ 0xca, 0x01, /* 428 */
+ 0xcb, 0x01, /* 429 */
+ 0xc8, 0x01, /* 430 */
+ 0xc7, 0x01, /* 431 */
+ 0x1a, 0x2d, /* 432 */
+ 0x30, 0x08, /* 433 */
+ 0x21, 0x1f, /* 434 */
+ 0xcb, 0x29, /* 435 */
+ 0x2d, 0x04, /* 436 */
+ 0xb1, 0x00, /* 437 */
+ 0x47, 0x30, /* 438 */
+ 0x9c, 0x00, /* 439 */
+ 0x31, 0x08, /* 440 */
+ 0x9e, 0x00, /* 441 */
+ 0x21, 0x1e, /* 442 */
+ 0xca, 0x29, /* 443 */
+ 0x4e, 0x30, /* 444 */
+ 0x9c, 0x00, /* 445 */
+ 0x1e, 0x14, /* 446 */
+ 0x9e, 0x01, /* 447 */
+ 0x66, 0x30, /* 448 */
+ 0x9c, 0x00, /* 449 */
+ 0x00, 0x00, /* 450 */
+ 0xa1, 0x11, /* 451 */
+ 0x1d, 0x18, /* 452 */
+ 0xa1, 0x15, /* 453 */
+ 0x83, 0x12, /* 454 */
+ 0x03, 0x13, /* 455 */
+ 0xa1, 0x1d, /* 456 */
+ 0xc0, 0x29, /* 457 */
+ 0x30, 0x08, /* 458 */
+ 0x38, 0x3a, /* 459 */
+ 0x03, 0x1d, /* 460 */
+ 0xc9, 0x2a, /* 461 */
+ 0x21, 0x1f, /* 462 */
+ 0xdc, 0x29, /* 463 */
+ 0x1e, 0x30, /* 464 */
+ 0x9c, 0x00, /* 465 */
+ 0x1e, 0x14, /* 466 */
+ 0x1d, 0x30, /* 467 */
+ 0x9c, 0x00, /* 468 */
+ 0x1e, 0x14, /* 469 */
+ 0xa3, 0x01, /* 470 */
+ 0xb6, 0x01, /* 471 */
+ 0x03, 0x30, /* 472 */
+ 0x32, 0x02, /* 473 */
+ 0x03, 0x18, /* 474 */
+ 0x2d, 0x17, /* 475 */
+ 0x21, 0x1b, /* 476 */
+ 0xa0, 0x19, /* 477 */
+ 0xb2, 0x2a, /* 478 */
+ 0x20, 0x30, /* 479 */
+ 0x9c, 0x00, /* 480 */
+ 0x1e, 0x14, /* 481 */
+ 0x12, 0x30, /* 482 */
+ 0x9c, 0x00, /* 483 */
+ 0x9e, 0x01, /* 484 */
+ 0x13, 0x30, /* 485 */
+ 0x9c, 0x00, /* 486 */
+ 0x9e, 0x01, /* 487 */
+ 0x14, 0x30, /* 488 */
+ 0x9c, 0x00, /* 489 */
+ 0x1e, 0x14, /* 490 */
+ 0x41, 0x30, /* 491 */
+ 0x9c, 0x00, /* 492 */
+ 0x9e, 0x01, /* 493 */
+ 0x15, 0x30, /* 494 */
+ 0x9c, 0x00, /* 495 */
+ 0x1e, 0x14, /* 496 */
+ 0x16, 0x30, /* 497 */
+ 0x9c, 0x00, /* 498 */
+ 0x1e, 0x14, /* 499 */
+ 0x17, 0x30, /* 500 */
+ 0x9c, 0x00, /* 501 */
+ 0x1e, 0x14, /* 502 */
+ 0x18, 0x30, /* 503 */
+ 0x9c, 0x00, /* 504 */
+ 0x1e, 0x14, /* 505 */
+ 0x19, 0x30, /* 506 */
+ 0x9c, 0x00, /* 507 */
+ 0x1e, 0x14, /* 508 */
+ 0x1a, 0x30, /* 509 */
+ 0x9c, 0x00, /* 510 */
+ 0x1e, 0x14, /* 511 */
+ 0x48, 0x30, /* 512 */
+ 0x9c, 0x00, /* 513 */
+ 0x1e, 0x14, /* 514 */
+ 0x1e, 0x30, /* 515 */
+ 0x9c, 0x00, /* 516 */
+ 0x1e, 0x14, /* 517 */
+ 0x1d, 0x30, /* 518 */
+ 0x9c, 0x00, /* 519 */
+ 0x1e, 0x14, /* 520 */
+ 0x4c, 0x30, /* 521 */
+ 0x9c, 0x00, /* 522 */
+ 0x1e, 0x14, /* 523 */
+ 0x4b, 0x30, /* 524 */
+ 0x9c, 0x00, /* 525 */
+ 0x1e, 0x14, /* 526 */
+ 0x50, 0x30, /* 527 */
+ 0x9c, 0x00, /* 528 */
+ 0x1e, 0x14, /* 529 */
+ 0x42, 0x30, /* 530 */
+ 0x9c, 0x00, /* 531 */
+ 0x1e, 0x14, /* 532 */
+ 0x21, 0x30, /* 533 */
+ 0x9c, 0x00, /* 534 */
+ 0x1e, 0x14, /* 535 */
+ 0x22, 0x30, /* 536 */
+ 0x9c, 0x00, /* 537 */
+ 0x1e, 0x14, /* 538 */
+ 0x40, 0x30, /* 539 */
+ 0x9c, 0x00, /* 540 */
+ 0x9e, 0x01, /* 541 */
+ 0x0b, 0x30, /* 542 */
+ 0x9c, 0x00, /* 543 */
+ 0x00, 0x00, /* 544 */
+ 0x20, 0x11, /* 545 */
+ 0x1d, 0x18, /* 546 */
+ 0x20, 0x15, /* 547 */
+ 0x0a, 0x30, /* 548 */
+ 0x83, 0x12, /* 549 */
+ 0x03, 0x13, /* 550 */
+ 0x9c, 0x00, /* 551 */
+ 0x00, 0x00, /* 552 */
+ 0x20, 0x10, /* 553 */
+ 0x1d, 0x18, /* 554 */
+ 0x20, 0x14, /* 555 */
+ 0x09, 0x30, /* 556 */
+ 0x9c, 0x00, /* 557 */
+ 0x00, 0x00, /* 558 */
+ 0xa0, 0x12, /* 559 */
+ 0x1d, 0x18, /* 560 */
+ 0xa0, 0x16, /* 561 */
+ 0xbb, 0x01, /* 562 */
+ 0xbc, 0x01, /* 563 */
+ 0xa2, 0x01, /* 564 */
+ 0xa4, 0x01, /* 565 */
+ 0xd6, 0x30, /* 566 */
+ 0x99, 0x21, /* 567 */
+ 0x70, 0x08, /* 568 */
+ 0xc5, 0x00, /* 569 */
+ 0x71, 0x08, /* 570 */
+ 0xc6, 0x00, /* 571 */
+ 0xd3, 0x30, /* 572 */
+ 0x8a, 0x15, /* 573 */
+ 0xe1, 0x24, /* 574 */
+ 0xb3, 0x00, /* 575 */
+ 0xd2, 0x30, /* 576 */
+ 0x8a, 0x15, /* 577 */
+ 0xe1, 0x24, /* 578 */
+ 0xac, 0x00, /* 579 */
+ 0xd4, 0x30, /* 580 */
+ 0x8a, 0x15, /* 581 */
+ 0xe1, 0x24, /* 582 */
+ 0x8a, 0x11, /* 583 */
+ 0xb4, 0x00, /* 584 */
+ 0xd1, 0x30, /* 585 */
+ 0x99, 0x21, /* 586 */
+ 0x70, 0x08, /* 587 */
+ 0xbd, 0x00, /* 588 */
+ 0x71, 0x08, /* 589 */
+ 0xbe, 0x00, /* 590 */
+ 0xd7, 0x30, /* 591 */
+ 0x8a, 0x15, /* 592 */
+ 0xe1, 0x24, /* 593 */
+ 0x8a, 0x11, /* 594 */
+ 0xc9, 0x00, /* 595 */
+ 0x3d, 0x08, /* 596 */
+ 0xd0, 0x00, /* 597 */
+ 0x3e, 0x08, /* 598 */
+ 0xd1, 0x00, /* 599 */<