On 7/23/07, Manu Abraham <abraham.manu@xxxxxxxxx> wrote:
Hi all, On one of the devices that i am working upon, it has a bus control entity. ie The device looks like this The device consists of 1) a BUS Interface Unit 2) on this bus Interface unit (BIU) there is one single physical I2C bus 3) a built in MASTER demodulator The I2C bus on the device is _not_ directly connected to any peripherals such as demods and or tuners. The bus goes to a control unit where the bus is split into 2 based on a control word sent to the Bus Control Unit (BCU) The split out bus goes out like this 1) goes to the MASTER tuner for the built in demodulator 2) goes to a SLAVE demodulator, which has just one switchable I2C output for the tuner ie , the configuration looks like 2, 2 way switches cascaded together, when the MASTER and SLAVE demodulators are cascaded. Looking at the device and thinking a lot, i don't see how the control can fit in as a part of the frontend at all, as the it has nothing to do with the frontend, but just the BIU. Some thought that i have, at present go like this * register independant virtual buses for each device, on device access, the relevant control word is appended to the BIU device register. * have one bus alone, but add a control for the bus such that the control can be initiated from some place, but as i explained, this control is not on the frontend/demodulator but on the Host controller.
Replying to my own mail: one second thoughts wondered whether i was abstract a bit. Other than that when Christoph asked me on IRC on the same, figured out that it was indeed a bit so. The device what i mentioned has 2 demodulators and 2 tuners on one physical I2C bus, which are accessed by selectively switching between them, since the I2C addresses for the demods are the same. The only separation being the switch. So eventually, since words can be abstract, i prefer to depict it with some code and comments alongwith. Attached is the code that would control the tuner as well as the MASTER/SLAVE demods. A note to Patrick: currently i am using the dvb-usb infrastructure. In the current state dvb-usb uses one single I2C bus, if i were to use virtual busses to utilize the MASTER/SLAVE combination, with a Control Word Magic being sent to the device at the time of accessing the virtual bus, eventually it goes down through the same physical bus. The issue that i a facing i have depicted as comments in the code itself Regards, Manu
#define AF901x_GETFIELD(bitf, val) ((val >> AF901x_OFFST_##bitf) & \ ((1 << AF901x_WIDTH_##bitf) - 1)) #define AF901x_SETFIELD(bitf, mask, val)(mask = (mask & (~(((1 << AF901x_WIDTH_##bitf) - 1)<< \ AF901x_OFFST_##bitf))) | (val << AF901x_OFFST_##bitf)) #define AF901x_BYPASS_HOST2TUNER 0xd607 #define AF901x_WIDTH_BYPASS_HOST2TUNER 1 #define AF901x_OFFST_BYPASS_HOST2TUNER 2 #define AF901x_I2CREG_SEL_TUNER 0xd417 #define AF901x_WIDTH_I2CREG_SEL_TUNER 1 #define AF901x_OFFST_I2CREG_SEL_TUNER 3 /** * NOTE! What we do here is not a simple Tuner I2C Bus enable/disable ! * What's performed here is a 2 way switch kind of operation where * the bus is switched between the demodulator and the tuner * * Of course we have a workaround (we have to), the enable bit can be * used for enabling the tuner, which means the demodulator is disabled. * * A case where we get totally confused is when we have MASTER/SLAVE * combinations * * The worst problem that we can have here: once we switch the * tuner bypass ON and expecting an error and the transaction aborts, * The driver expects the device to be communicating to the demodulator, * but in reality we are talking to the tuner in fact. * * A workaround for this would be to cache the gate switched state * into the device state structure, whereby a possible operation * returned success state is used to switch the gate status back to the * original position, such that normal communication can continue with * the demodulator. * * But with all these workarounds don't we look ugly ? Any better ways * of accomplishing this ? */ static int af901x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { u8 reg; if (slave) { /** * Additionally, we need to tell the BCU that we are * talking to the SLAVE, How ? */ af901x_read_reg(state, AF901x_BYPASS_HOST2TUNER, ®); if (enable) reg = AF901x_SETFIELD(BYPASS_HOST2TUNER, reg, 1); else reg = AF901x_SETFIELD(BYPASS_HOST2TUNER, reg, 0); /** * Additionally, we need to tell the BCU that we are * talking to the SLAVE, How ? */ af901x_write_reg(state, AF901x_BYPASS_HOST2TUNER, reg); } else { /** * Additionally, we need to tell the BCU that we are * talking to the MASTER, How ? */ af901x_read_reg(state, AF901x_I2CREG_SEL_TUNER, ®); if (enable) reg = AF901x_GETFIELD(I2CREG_SEL_TUNER, reg, 1); else reg = AF901x_GETFIELD(I2CREG_SEL_TUNER, reg, 0); /** * Additionally, we need to tell the BCU that we are * talking to the MASTER, How ? */ af901x_write_reg(state, AF901x_I2CREG_SEL_TUNER, reg); } return 0; }
_______________________________________________ linux-dvb mailing list linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb