public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [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