* [PATCH 3/4] Modifications to the driver mb86a20s
@ 2011-05-13 2:11 Manoel PN
2011-05-13 7:20 ` Mauro Carvalho Chehab
0 siblings, 1 reply; 2+ messages in thread
From: Manoel PN @ 2011-05-13 2:11 UTC (permalink / raw)
To: linux-media, Mauro Chehab, lgspn
[-- Attachment #1: Type: text/plain, Size: 1611 bytes --]
This patch implements some modifications in the function
This patch implements some modifications in the initialization function of the mb86a20s.
Explanation:
Several registers of mb86a20s can be programmed and to simplify this task and due to lack of technical literature to elaborate the necessary calculations was opted by the sending of values already ready for the registers, eliminating the process of calculations.
The technique is quite simple: to each register that can be modified an identification (REGxxxx_IDCFG) was attributed and those that do not need modification was attributed REG_IDCFG_NONE.
The device that uses the demodulator mb86a20s simply informs the registers to be modified through the configuration parameter of the function frontend_attach.
Like in the example:
static struct mb86a20s_config_regs_val mb86a20s_config_regs[] = {
{ REG2820_IDCFG, 0x33ddcd },
{ REG50D5_IDCFG, 0x00 }, /* use output TS parallel */
{ REG50D6_IDCFG, 0x17 }
};
static struct mb86a20s_config mb86a20s_cfg = {
.demod_address = DEMOD_I2C_ADDR,
.config_regs_size = ARRAY_SIZE(mb86a20s_config_regs),
.config_regs = mb86a20s_config_regs,
};
If there are no registers to be modified to do just this:
static struct mb86a20s_config mb86a20s_cfg = {
.demod_address = DEMOD_I2C_ADDR,
};
static int tbs_dtb08_frontend_attach(struct dvb_usb_adapter *adap)
{
adap->fe = dvb_attach(mb86a20s_attach, &mb86a20s_cfg, &adap->dev->i2c_adap);
if (adap->fe) {
frontend_tuner_attach(adap);
}
}
Signed-off-by: Manoel Pinheiro <pinusdtv@hotmail.com>
[-- Attachment #2: regs_init.patch --]
[-- Type: application/octet-stream, Size: 18590 bytes --]
diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb/frontends/mb86a20s.c
index 0f867a5..d1cdc5f 100644
--- a/drivers/media/dvb/frontends/mb86a20s.c
+++ b/drivers/media/dvb/frontends/mb86a20s.c
@@ -1,6 +1,7 @@
/*
* Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
*
+ * Copyright (C) 2011 Manoel Pinheiro <pinusdtv@hotmail.com>
* Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
* Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
*
@@ -44,6 +45,8 @@ struct mb86a20s_state {
struct dvb_frontend frontend;
+ int config_regs_size;
+ const struct mb86a20s_config_regs_val *config_regs;
bool need_init;
};
@@ -52,254 +55,120 @@ struct regdata {
u8 data;
};
+struct mb86a20s_config_regs {
+ u8 id_cfg;
+ u8 type; /* 0=8 bits wo/sub, 1=8 bits w/sub
+ * 2=16 bits wo/sub, 3=16 bits w/sub, 4=24 bits */
+ u8 reg;
+ u8 subreg;
+ u32 init_val;
+};
+
/*
+ * Several registers of mb86a20s can be programmed and to simplify this task
+ * and due to lack of technical literature to elaborate the necessary
+ * calculations was opted by the sending of values already ready for the
+ * registers, eliminating the process of calculations.
+ * The technique is quite simple: to each register that can be modified an
+ * identification (REGxxxx_IDCFG) was attributed and those that do not need
+ * modification was attributed REG_IDCFG_NONE.
+ *
* Initialization sequence: Use whatevere default values that PV SBTVD
* does on its initialisation, obtained via USB snoop
*/
-static struct regdata mb86a20s_init[] = {
- { 0x70, 0x0f },
- { 0x70, 0xff },
- { 0x08, 0x01 },
- { 0x09, 0x3e },
- { 0x50, 0xd1 },
- { 0x51, 0x22 },
- { 0x39, 0x01 },
- { 0x71, 0x00 },
- { 0x28, 0x2a },
- { 0x29, 0x00 },
- { 0x2a, 0xff },
- { 0x2b, 0x80 },
- { 0x28, 0x20 },
- { 0x29, 0x33 },
- { 0x2a, 0xdf },
- { 0x2b, 0xa9 },
- { 0x3b, 0x21 },
- { 0x3c, 0x3a },
- { 0x01, 0x0d },
- { 0x04, 0x08 },
- { 0x05, 0x05 },
- { 0x04, 0x0e },
- { 0x05, 0x00 },
- { 0x04, 0x0f },
- { 0x05, 0x14 },
- { 0x04, 0x0b },
- { 0x05, 0x8c },
- { 0x04, 0x00 },
- { 0x05, 0x00 },
- { 0x04, 0x01 },
- { 0x05, 0x07 },
- { 0x04, 0x02 },
- { 0x05, 0x0f },
- { 0x04, 0x03 },
- { 0x05, 0xa0 },
- { 0x04, 0x09 },
- { 0x05, 0x00 },
- { 0x04, 0x0a },
- { 0x05, 0xff },
- { 0x04, 0x27 },
- { 0x05, 0x64 },
- { 0x04, 0x28 },
- { 0x05, 0x00 },
- { 0x04, 0x1e },
- { 0x05, 0xff },
- { 0x04, 0x29 },
- { 0x05, 0x0a },
- { 0x04, 0x32 },
- { 0x05, 0x0a },
- { 0x04, 0x14 },
- { 0x05, 0x02 },
- { 0x04, 0x04 },
- { 0x05, 0x00 },
- { 0x04, 0x05 },
- { 0x05, 0x22 },
- { 0x04, 0x06 },
- { 0x05, 0x0e },
- { 0x04, 0x07 },
- { 0x05, 0xd8 },
- { 0x04, 0x12 },
- { 0x05, 0x00 },
- { 0x04, 0x13 },
- { 0x05, 0xff },
- { 0x52, 0x01 },
- { 0x50, 0xa7 },
- { 0x51, 0x00 },
- { 0x50, 0xa8 },
- { 0x51, 0xff },
- { 0x50, 0xa9 },
- { 0x51, 0xff },
- { 0x50, 0xaa },
- { 0x51, 0x00 },
- { 0x50, 0xab },
- { 0x51, 0xff },
- { 0x50, 0xac },
- { 0x51, 0xff },
- { 0x50, 0xad },
- { 0x51, 0x00 },
- { 0x50, 0xae },
- { 0x51, 0xff },
- { 0x50, 0xaf },
- { 0x51, 0xff },
- { 0x5e, 0x07 },
- { 0x50, 0xdc },
- { 0x51, 0x01 },
- { 0x50, 0xdd },
- { 0x51, 0xf4 },
- { 0x50, 0xde },
- { 0x51, 0x01 },
- { 0x50, 0xdf },
- { 0x51, 0xf4 },
- { 0x50, 0xe0 },
- { 0x51, 0x01 },
- { 0x50, 0xe1 },
- { 0x51, 0xf4 },
- { 0x50, 0xb0 },
- { 0x51, 0x07 },
- { 0x50, 0xb2 },
- { 0x51, 0xff },
- { 0x50, 0xb3 },
- { 0x51, 0xff },
- { 0x50, 0xb4 },
- { 0x51, 0xff },
- { 0x50, 0xb5 },
- { 0x51, 0xff },
- { 0x50, 0xb6 },
- { 0x51, 0xff },
- { 0x50, 0xb7 },
- { 0x51, 0xff },
- { 0x50, 0x50 },
- { 0x51, 0x02 },
- { 0x50, 0x51 },
- { 0x51, 0x04 },
- { 0x45, 0x04 },
- { 0x48, 0x04 },
- { 0x50, 0xd5 },
- { 0x51, 0x01 }, /* Serial */
- { 0x50, 0xd6 },
- { 0x51, 0x1f },
- { 0x50, 0xd2 },
- { 0x51, 0x03 },
- { 0x50, 0xd7 },
- { 0x51, 0x3f },
- { 0x1c, 0x01 },
- { 0x28, 0x06 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x03 },
- { 0x28, 0x07 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x0d },
- { 0x28, 0x08 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x02 },
- { 0x28, 0x09 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x01 },
- { 0x28, 0x0a },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x21 },
- { 0x28, 0x0b },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x29 },
- { 0x28, 0x0c },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x16 },
- { 0x28, 0x0d },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x31 },
- { 0x28, 0x0e },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x0e },
- { 0x28, 0x0f },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x4e },
- { 0x28, 0x10 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x46 },
- { 0x28, 0x11 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x0f },
- { 0x28, 0x12 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x56 },
- { 0x28, 0x13 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x35 },
- { 0x28, 0x14 },
- { 0x29, 0x00 },
- { 0x2a, 0x01 },
- { 0x2b, 0xbe },
- { 0x28, 0x15 },
- { 0x29, 0x00 },
- { 0x2a, 0x01 },
- { 0x2b, 0x84 },
- { 0x28, 0x16 },
- { 0x29, 0x00 },
- { 0x2a, 0x03 },
- { 0x2b, 0xee },
- { 0x28, 0x17 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x98 },
- { 0x28, 0x18 },
- { 0x29, 0x00 },
- { 0x2a, 0x00 },
- { 0x2b, 0x9f },
- { 0x28, 0x19 },
- { 0x29, 0x00 },
- { 0x2a, 0x07 },
- { 0x2b, 0xb2 },
- { 0x28, 0x1a },
- { 0x29, 0x00 },
- { 0x2a, 0x06 },
- { 0x2b, 0xc2 },
- { 0x28, 0x1b },
- { 0x29, 0x00 },
- { 0x2a, 0x07 },
- { 0x2b, 0x4a },
- { 0x28, 0x1c },
- { 0x29, 0x00 },
- { 0x2a, 0x01 },
- { 0x2b, 0xbc },
- { 0x28, 0x1d },
- { 0x29, 0x00 },
- { 0x2a, 0x04 },
- { 0x2b, 0xba },
- { 0x28, 0x1e },
- { 0x29, 0x00 },
- { 0x2a, 0x06 },
- { 0x2b, 0x14 },
- { 0x50, 0x1e },
- { 0x51, 0x5d },
- { 0x50, 0x22 },
- { 0x51, 0x00 },
- { 0x50, 0x23 },
- { 0x51, 0xc8 },
- { 0x50, 0x24 },
- { 0x51, 0x00 },
- { 0x50, 0x25 },
- { 0x51, 0xf0 },
- { 0x50, 0x26 },
- { 0x51, 0x00 },
- { 0x50, 0x27 },
- { 0x51, 0xc3 },
- { 0x50, 0x39 },
- { 0x51, 0x02 },
- { 0x50, 0xd5 },
- { 0x51, 0x01 },
- { 0xd0, 0x00 },
+static struct mb86a20s_config_regs mb86a20s_init[] = {
+ { REG_IDCFG_NONE, 0x00, 0x70, 0x00, 0x0f },
+ { REG_IDCFG_NONE, 0x00, 0x70, 0x00, 0xff },
+ { REG_IDCFG_NONE, 0x00, 0x08, 0x00, 0x01 },
+ { REG09_IDCFG, 0x00, 0x09, 0x00, 0x3e },
+ { REG50D1_IDCFG, 0x01, 0x50, 0xd1, 0x22 },
+ { REG39_IDCFG, 0x00, 0x39, 0x00, 0x01 },
+ { REG71_IDCFG, 0x00, 0x71, 0x00, 0x00 },
+ { REG282A_IDCFG, 0x04, 0x28, 0x2a, 0xff80 },
+ { REG2820_IDCFG, 0x04, 0x28, 0x20, 0x33dfa9 },
+ { REG2822_IDCFG, 0x04, 0x28, 0x22, 0x1ff0 },
+ { REG_IDCFG_NONE, 0x00, 0x3b, 0x00, 0x21 },
+ { REG3C_IDCFG, 0x00, 0x3c, 0x00, 0x3a },
+ { REG01_IDCFG, 0x00, 0x01, 0x00, 0x0d },
+ { REG0408_IDCFG, 0x01, 0x04, 0x08, 0x05 },
+ { REG040E_IDCFG, 0x03, 0x04, 0x0e, 0x0014 },
+ { REG040B_IDCFG, 0x01, 0x04, 0x0b, 0x8c },
+ { REG0400_IDCFG, 0x03, 0x04, 0x00, 0x0007 },
+ { REG0402_IDCFG, 0x03, 0x04, 0x02, 0x0fa0 },
+ { REG0409_IDCFG, 0x01, 0x04, 0x09, 0x00 },
+ { REG040A_IDCFG, 0x01, 0x04, 0x0a, 0xff },
+ { REG0427_IDCFG, 0x01, 0x04, 0x27, 0x64 },
+ { REG0428_IDCFG, 0x01, 0x04, 0x28, 0x00 },
+ { REG041E_IDCFG, 0x01, 0x04, 0x1e, 0xff },
+ { REG0429_IDCFG, 0x01, 0x04, 0x29, 0x0a },
+ { REG0432_IDCFG, 0x01, 0x04, 0x32, 0x0a },
+ { REG0414_IDCFG, 0x01, 0x04, 0x14, 0x02 },
+ { REG0404_IDCFG, 0x03, 0x04, 0x04, 0x0022 },
+ { REG0406_IDCFG, 0x03, 0x04, 0x06, 0x0ed8 },
+ { REG0412_IDCFG, 0x01, 0x04, 0x12, 0x00 },
+ { REG0413_IDCFG, 0x01, 0x04, 0x13, 0xff },
+ { REG0415_IDCFG, 0x01, 0x04, 0x15, 0x4e },
+ { REG0416_IDCFG, 0x01, 0x04, 0x16, 0x20 },
+ { REG_IDCFG_NONE, 0x00, 0x52, 0x00, 0x01 },
+ { REG50A7_IDCFG, 0x04, 0x50, 0xa7, 0xffff },
+ { REG50AA_IDCFG, 0x04, 0x50, 0xaa,0xffff },
+ { REG50AD_IDCFG, 0x04, 0x50, 0xad, 0xffff },
+ { REG_IDCFG_NONE, 0x00, 0x5e, 0x00, 0x07 },
+ { REG50DC_IDCFG, 0x03, 0x50, 0xdc, 0x01f4 },
+ { REG50DE_IDCFG, 0x03, 0x50, 0xde, 0x01f4 },
+ { REG50E0_IDCFG, 0x03, 0x50, 0xe0, 0x01f4 },
+ { REG50B0_IDCFG, 0x01, 0x50, 0xb0, 0x07 },
+ { REG50B2_IDCFG, 0x03, 0x50, 0xb2, 0xffff },
+ { REG50B4_IDCFG, 0x03, 0x50, 0xb4, 0xffff },
+ { REG50B6_IDCFG, 0x03, 0x50, 0xb6, 0xffff },
+ { REG5050_IDCFG, 0x01, 0x50, 0x50, 0x02 },
+ { REG5051_IDCFG, 0x01, 0x50, 0x51, 0x04 },
+ { REG45_IDCFG, 0x00, 0x45, 0x00, 0x04 },
+ { REG_IDCFG_NONE, 0x00, 0x48, 0x00, 0x04 },
+ { REG50D5_IDCFG, 0x01, 0x50, 0xd5, 0x01 },
+ { REG50D6_IDCFG, 0x01, 0x50, 0xd6, 0x1f },
+ { REG50D2_IDCFG, 0x01, 0x50, 0xd2, 0x03 },
+ { REG50D7_IDCFG, 0x01, 0x50, 0xd7, 0x3f },
+ { REG2874_IDCFG, 0x04, 0x28, 0x74, 0x0040 },
+ { REG2846_IDCFG, 0x04, 0x28, 0x46, 0x2c0c },
+ { REG0440_IDCFG, 0x01, 0x04, 0x40, 0x01 },
+ { REG2800_IDCFG, 0x01, 0x28, 0x00, 0x10 },
+ { REG2805_IDCFG, 0x01, 0x28, 0x05, 0x02 },
+ { REG_IDCFG_NONE, 0x00, 0x1c, 0x00, 0x01 },
+ { REG2806_IDCFG, 0x04, 0x28, 0x06, 0x0003 },
+ { REG2807_IDCFG, 0x04, 0x28, 0x07, 0x000d },
+ { REG2808_IDCFG, 0x04, 0x28, 0x08, 0x0002 },
+ { REG2809_IDCFG, 0x04, 0x28, 0x09, 0x0001 },
+ { REG280A_IDCFG, 0x04, 0x28, 0x0a, 0x0021 },
+ { REG280B_IDCFG, 0x04, 0x28, 0x0b, 0x0029 },
+ { REG280C_IDCFG, 0x04, 0x28, 0x0c, 0x0016 },
+ { REG280D_IDCFG, 0x04, 0x28, 0x0d, 0x0031 },
+ { REG280E_IDCFG, 0x04, 0x28, 0x0e, 0x000e },
+ { REG280F_IDCFG, 0x04, 0x28, 0x0f, 0x004e },
+ { REG2810_IDCFG, 0x04, 0x28, 0x10, 0x0046 },
+ { REG2811_IDCFG, 0x04, 0x28, 0x11, 0x000f },
+ { REG2812_IDCFG, 0x04, 0x28, 0x12, 0x0056 },
+ { REG2813_IDCFG, 0x04, 0x28, 0x13, 0x0035 },
+ { REG2814_IDCFG, 0x04, 0x28, 0x14, 0x01be },
+ { REG2815_IDCFG, 0x04, 0x28, 0x15, 0x0184 },
+ { REG2816_IDCFG, 0x04, 0x28, 0x16, 0x03ee },
+ { REG2817_IDCFG, 0x04, 0x28, 0x17, 0x0098 },
+ { REG2818_IDCFG, 0x04, 0x28, 0x18, 0x009f },
+ { REG2819_IDCFG, 0x04, 0x28, 0x19, 0x07b2 },
+ { REG281A_IDCFG, 0x04, 0x28, 0x1a, 0x06c2 },
+ { REG281B_IDCFG, 0x04, 0x28, 0x1b, 0x074a },
+ { REG281C_IDCFG, 0x04, 0x28, 0x1c, 0x01bc },
+ { REG281D_IDCFG, 0x04, 0x28, 0x1d, 0x04ba },
+ { REG281E_IDCFG, 0x04, 0x28, 0x1e, 0x0614 },
+ { REG501E_IDCFG, 0x01, 0x50, 0x1e, 0x5d },
+ { REG5022_IDCFG, 0x01, 0x50, 0x22, 0x00 },
+ { REG5023_IDCFG, 0x01, 0x50, 0x23, 0xc8 },
+ { REG5024_IDCFG, 0x01, 0x50, 0x24, 0x00 },
+ { REG5025_IDCFG, 0x01, 0x50, 0x25, 0xf0 },
+ { REG5026_IDCFG, 0x01, 0x50, 0x26, 0x00 },
+ { REG5027_IDCFG, 0x01, 0x50, 0x27, 0xc3 },
+ { REG5039_IDCFG, 0x01, 0x50, 0x39, 0x02 },
+ { REG286A_IDCFG, 0x04, 0x28, 0x6a, 0x0000 }
};
static struct regdata mb86a20s_reset_reception[] = {
@@ -370,37 +239,105 @@ static int mb86a20s_i2c_readreg(struct mb86a20s_state *state,
mb86a20s_i2c_writeregdata(state, state->config->demod_address, \
regdata, ARRAY_SIZE(regdata))
-static int mb86a20s_initfe(struct dvb_frontend *fe)
+static u32 get_config_reg_val(struct mb86a20s_state *state, u8 id_cfg, u32 default_val)
{
- struct mb86a20s_state *state = fe->demodulator_priv;
- int rc;
- u8 regD5 = 1;
-
- dprintk("\n");
+ if (state->config_regs != NULL) {
+ int i;
+ for (i = 0; i < state->config_regs_size; i++) {
+ if (state->config_regs[i].id_cfg == id_cfg)
+ return state->config_regs[i].init_val;
+ }
+ }
+ return default_val;
+}
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0);
+static int mb86a20s_regs_init(struct mb86a20s_state *state)
+{
+ int i, rc;
- /* Initialize the frontend */
- rc = mb86a20s_writeregdata(state, mb86a20s_init);
- if (rc < 0)
- goto err;
+ state->need_init = 1;
- if (!state->config->is_serial) {
- regD5 &= ~1;
+ for (i = 0; i < ARRAY_SIZE(mb86a20s_init); i++) {
+ struct mb86a20s_config_regs *reg_val = &mb86a20s_init[i];
+ u32 val = reg_val->init_val;
+ if (reg_val->id_cfg != REG_IDCFG_NONE && state->config_regs)
+ val = get_config_reg_val(state, reg_val->id_cfg, val);
- rc = mb86a20s_writereg(state, 0x50, 0xd5);
- if (rc < 0)
- goto err;
- rc = mb86a20s_writereg(state, 0x51, regD5);
- if (rc < 0)
- goto err;
+ switch (reg_val->type) {
+ case 0:
+ rc = mb86a20s_writereg(state, reg_val->reg, val);
+ if (rc < 0) return rc;
+ break;
+ case 1:
+ rc = mb86a20s_writereg(state, reg_val->reg, reg_val->subreg);
+ if (rc < 0) return rc;
+ if (reg_val->reg == 0x28)
+ rc = mb86a20s_writereg(state, 0x2b, val);
+ else
+ rc = mb86a20s_writereg(state, reg_val->reg + 1, val);
+ if (rc < 0) return rc;
+ break;
+ case 2:
+ rc = mb86a20s_writereg(state, reg_val->reg, (u8)(val >> 0x08));
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, reg_val->reg + 1, (u8)val);
+ if (rc < 0) return rc;
+ break;
+ case 3:
+ rc = mb86a20s_writereg(state, reg_val->reg, reg_val->subreg);
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, reg_val->reg + 1, (u8)(val >> 0x08));
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, reg_val->reg, reg_val->subreg + 1);
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, reg_val->reg + 1, (u8)val);
+ if (rc < 0) return rc;
+ break;
+ case 4:
+ if (reg_val->reg == 0x28) {
+ rc = mb86a20s_writereg(state, 0x28, reg_val->subreg);
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, 0x29, (u8)(val >> 0x10));
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, 0x2a, (u8)(val >> 0x08));
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, 0x2b, (u8)val);
+ if (rc < 0) return rc;
+ }
+ else if (reg_val->reg == 0x50) {
+ rc = mb86a20s_writereg(state, reg_val->reg, reg_val->subreg);
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, reg_val->reg + 1, (u8)(val >> 0x10));
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, reg_val->reg, reg_val->subreg + 1);
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, reg_val->reg + 1, (u8)(val >> 0x08));
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, reg_val->reg, reg_val->subreg + 2);
+ if (rc < 0) return rc;
+ rc = mb86a20s_writereg(state, reg_val->reg + 1, (u8)val);
+ if (rc < 0) return rc;
+ }
+ else
+ return -1;
+ break;
+ default:
+ return -1;
+ }
}
+ state->need_init = 0;
+ return 0;
+}
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
+static int mb86a20s_initfe(struct dvb_frontend *fe)
+{
+ struct mb86a20s_state *state = fe->demodulator_priv;
+ int rc;
+
+ dprintk("\n");
-err:
+ /* Initialize the demodulator */
+ rc = mb86a20s_regs_init(state);
if (rc < 0) {
state->need_init = true;
printk(KERN_INFO "mb86a20s: Init failed. Will try again later\n");
@@ -582,6 +519,8 @@ struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
/* setup the state */
state->config = config;
state->i2c = i2c;
+ state->config_regs_size = config->config_regs_size;
+ state->config_regs = config->config_regs;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &mb86a20s_ops,
@@ -636,4 +575,5 @@ static struct dvb_frontend_ops mb86a20s_ops = {
MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Manoel Pinheiro <pinusdtv@hotmail.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/mb86a20s.h b/drivers/media/dvb/frontends/mb86a20s.h
index bf22e77..c656020 100644
--- a/drivers/media/dvb/frontends/mb86a20s.h
+++ b/drivers/media/dvb/frontends/mb86a20s.h
@@ -1,6 +1,7 @@
/*
* Fujitsu mb86a20s driver
*
+ * Copyright (C) 2011 Manoel Pinheiro <pinusdtv@hotmail.com>
* Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
*
* This program is free software; you can redistribute it and/or
@@ -18,6 +19,104 @@
#include <linux/dvb/frontend.h>
+/*
+ * These IDCFG are unique identifiers for registers that can be assigned new values.
+ * New identifiers may be added to this list in ascending order.
+ * The unique identifier that can not have its value changed is REG_IDCFG_NONE
+ * which must be equal to zero.
+ * The values for IDCFG must be between 0x01 and 0xff (8 bits), for while.
+ */
+#define REG_IDCFG_NONE 0x00 /* do not change this ID */
+#define REG01_IDCFG 0x01
+#define REG0400_IDCFG 0x02
+#define REG0402_IDCFG 0x03
+#define REG0404_IDCFG 0x04
+#define REG0406_IDCFG 0x05
+#define REG0408_IDCFG 0x06
+#define REG0409_IDCFG 0x07
+#define REG040A_IDCFG 0x08
+#define REG040B_IDCFG 0x09
+#define REG040E_IDCFG 0x0a
+#define REG0412_IDCFG 0x0b
+#define REG0413_IDCFG 0x0c
+#define REG0414_IDCFG 0x0d
+#define REG0415_IDCFG 0x0e
+#define REG0416_IDCFG 0x0f
+#define REG041E_IDCFG 0x10
+#define REG0427_IDCFG 0x11
+#define REG0428_IDCFG 0x12
+#define REG0429_IDCFG 0x13
+#define REG0432_IDCFG 0x14
+#define REG0440_IDCFG 0x15
+#define REG09_IDCFG 0x16
+#define REG2800_IDCFG 0x17
+#define REG2805_IDCFG 0x18
+#define REG2806_IDCFG 0x19
+#define REG2807_IDCFG 0x1a
+#define REG2808_IDCFG 0x1b
+#define REG2809_IDCFG 0x1c
+#define REG280A_IDCFG 0x1d
+#define REG280B_IDCFG 0x1e
+#define REG280C_IDCFG 0x1f
+#define REG280D_IDCFG 0x20
+#define REG280E_IDCFG 0x21
+#define REG280F_IDCFG 0x22
+#define REG2810_IDCFG 0x23
+#define REG2811_IDCFG 0x24
+#define REG2812_IDCFG 0x25
+#define REG2813_IDCFG 0x26
+#define REG2814_IDCFG 0x27
+#define REG2815_IDCFG 0x28
+#define REG2816_IDCFG 0x29
+#define REG2817_IDCFG 0x2a
+#define REG2818_IDCFG 0x2b
+#define REG2819_IDCFG 0x2c
+#define REG281A_IDCFG 0x2d
+#define REG281B_IDCFG 0x2e
+#define REG281C_IDCFG 0x2f
+#define REG281D_IDCFG 0x30
+#define REG281E_IDCFG 0x31
+#define REG2820_IDCFG 0x32
+#define REG2822_IDCFG 0x33
+#define REG282A_IDCFG 0x34
+#define REG2846_IDCFG 0x35
+#define REG286A_IDCFG 0x36
+#define REG2874_IDCFG 0x37
+#define REG39_IDCFG 0x38
+#define REG3C_IDCFG 0x39
+#define REG45_IDCFG 0x3a
+#define REG501E_IDCFG 0x3b
+#define REG5022_IDCFG 0x3c
+#define REG5023_IDCFG 0x3d
+#define REG5024_IDCFG 0x3e
+#define REG5025_IDCFG 0x3f
+#define REG5026_IDCFG 0x40
+#define REG5027_IDCFG 0x41
+#define REG5039_IDCFG 0x42
+#define REG5050_IDCFG 0x43
+#define REG5051_IDCFG 0x44
+#define REG50A7_IDCFG 0x45
+#define REG50AA_IDCFG 0x46
+#define REG50AD_IDCFG 0x47
+#define REG50B0_IDCFG 0x48
+#define REG50B2_IDCFG 0x49
+#define REG50B4_IDCFG 0x4a
+#define REG50B6_IDCFG 0x4b
+#define REG50D1_IDCFG 0x4c
+#define REG50D2_IDCFG 0x4d
+#define REG50D5_IDCFG 0x4e
+#define REG50D6_IDCFG 0x4f
+#define REG50D7_IDCFG 0x50
+#define REG50DC_IDCFG 0x51
+#define REG50DE_IDCFG 0x52
+#define REG50E0_IDCFG 0x53
+#define REG71_IDCFG 0x54
+
+struct mb86a20s_config_regs_val {
+ u8 id_cfg;
+ u32 init_val;
+};
+
/**
* struct mb86a20s_config - Define the per-device attributes of the frontend
*
@@ -27,6 +126,8 @@
struct mb86a20s_config {
u8 demod_address;
bool is_serial;
+ int config_regs_size;
+ const struct mb86a20s_config_regs_val *config_regs;
};
#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 3/4] Modifications to the driver mb86a20s
2011-05-13 2:11 [PATCH 3/4] Modifications to the driver mb86a20s Manoel PN
@ 2011-05-13 7:20 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 2+ messages in thread
From: Mauro Carvalho Chehab @ 2011-05-13 7:20 UTC (permalink / raw)
To: Manoel PN; +Cc: linux-media, lgspn
Em 13-05-2011 04:11, Manoel PN escreveu:
> This patch implements some modifications in the function
>
> This patch implements some modifications in the initialization function of the mb86a20s.
>
> Explanation:
>
> Several registers of mb86a20s can be programmed and to simplify this task and due to lack of technical literature to elaborate the necessary calculations was opted by the sending of values already ready for the registers, eliminating the process of calculations.
Please, don't assume that because you don't have the specs that the driver needs
to be changed. Other people might have the specs.
Also, on several cases, the datasheets describe a common init sequence that
should be done in order to initialize the device, that is on several cases fixed.
So, on most cases, the better approach is to just put the init sequence into a
table. This also helps to easily fix the init sequence, if the vendor (or new
rev. engineering dumps) find that such default init sequence changed for whatever
reason (sometimes, vendors add some new init sequences on some errata, to fix some
hardware bug).
> The technique is quite simple: to each register that can be modified an identification (REGxxxx_IDCFG) was attributed and those that do not need modification was attributed REG_IDCFG_NONE.
>
> The device that uses the demodulator mb86a20s simply informs the registers to be modified through the configuration parameter of the function frontend_attach.
>
> Like in the example:
>
> static struct mb86a20s_config_regs_val mb86a20s_config_regs[] = {
> { REG2820_IDCFG, 0x33ddcd },
> { REG50D5_IDCFG, 0x00 }, /* use output TS parallel */
> { REG50D6_IDCFG, 0x17 }
> };
>
> static struct mb86a20s_config mb86a20s_cfg = {
> .demod_address = DEMOD_I2C_ADDR,
> .config_regs_size = ARRAY_SIZE(mb86a20s_config_regs),
> .config_regs = mb86a20s_config_regs,
> };
>
> If there are no registers to be modified to do just this:
>
> static struct mb86a20s_config mb86a20s_cfg = {
> .demod_address = DEMOD_I2C_ADDR,
> };
>
> static int tbs_dtb08_frontend_attach(struct dvb_usb_adapter *adap)
> {
> adap->fe = dvb_attach(mb86a20s_attach, &mb86a20s_cfg, &adap->dev->i2c_adap);
> if (adap->fe) {
> frontend_tuner_attach(adap);
> }
> }
>
>
>
> Signed-off-by: Manoel Pinheiro <pinusdtv@hotmail.com>
In this specific case, I think you're adding a more complex logic without a good
reason for it. Keep the code simple.
NACK.
> regs_init.patch
Commenting attached patches is harder, as emails don't like to reply for it.
The better is to always send patches inlined.
Mauro,
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-05-13 7:20 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-13 2:11 [PATCH 3/4] Modifications to the driver mb86a20s Manoel PN
2011-05-13 7:20 ` Mauro Carvalho Chehab
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox