Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] [PATCH] Legacy Dish Network switches



Based off the work that Jeremy Hall did 2 years ago, I have patch that
supports controlling legacy dish network switches (SW21, SW44, SW64,
etc)

The code itself is simple enough, and is added to the frontend code (st0299.c).

However, the question is, how do I call this code.  I came up  with 2 options:
1) add a new ioctl for it, and 2) overload the FE_DISEQC_SEND_MASTER_CMD ioctl.

I tried both methods.  Certainly adding a new ioctl is the easiest
one, however, it requires more work inside client applications.

I overloaded the FE_DISEQC_SEND_MASTER_CMD ioctl by looking for a
specific sequence (cmd->msg_len==3 && cmd->msg[0]=0xff &&
cmd->msg[1]=0xff)
which then calls the legacy switch code passing cmd->msg[2] as the argument.

However, you need to add support for this overloading in all modules
that try to preempt the frontend (av7110.c is one) so it requires
proliferating this hack into lots of places.
The upside to this method is that no modifications are needed to vdr
at all.  You just add the relevant codes to the diseqc.conf file, and
off you go.

The command sequence as implemented would be:

Cmd Model Input   Polarization
0x34 SW21 Dish 1       V
0xB4 SW21 Dish 1       H
0x65 SW21 Dish 2       V
0xE5 SW21 Dish 2       H
0x46 SW42 Dish 1       V
0xC6 SW42 Dish 1       H
0x17 SW42 Dish 2       V
0x97 SW42 Dish 2       H
0x68 SW44 Dish 2       V
0xE8 SW44 Dish 2       H
0x39 SW64 Dish 1A
0x1A SW64 Dish 1B
0x4B SW64 Dish 2A
0x5C SW64 Dish 2B
0x0D SW64 Dish 3A
0x2E SW64 Dish 3B
0x72 Twin LNB 1
0x23 Twin LNB 2
0x51 Quad LNB 2

A diseqc.conf file may look like:
S1 99999 V 11250 t [FF FF 65]
S1 99999 H 11250 t [FF FF E5]
S2 99999 V 11250 t [FF FF 34]
S2 99999 H 11250 t [FF FF B4]

If anyone has input on which solution would be better (new ioctl or
overloaded) please let me know.

Also, I am not sure how to switch between schedule_timeout and mdelay
(schedule_timeout is nicer, but  only accurate when HZ=1000 (or a
multiple of 8ms))  Both commands work fine with a 2.6 kernel on ia32

// #define CHECK_DISH_TIMING
static int stv0299_send_legacy_dish_cmd(struct dvb_i2c_bus *i2c, u32 cmd,
                        int tuner_type)
{
    u8 last = 1;
    int i;

#ifdef CHECK_DISH_TIMING
    struct timeval gtod[9],first;
    do_gettimeofday(&first);
#endif

/* reset voltage at the end
    if((0x50 & stv0299_readreg (i2c, 0x0c)) == 0x50)
      cmd |= 0x80;
    else
      cmd &= 0x7F;
*/
    cmd = cmd << 1;
    printk("%s switch command: 0x%04x\n",__FUNCTION__, cmd);

    stv0299_set_voltage(i2c,SEC_VOLTAGE_18,tuner_type);
    set_current_state(TASK_INTERRUPTIBLE);
    schedule_timeout ((HZ*32)/1000);
    // mdelay(32)

    for(i=0;i<9;i++) {
      if((cmd & 0x01) != last) {
        stv0299_set_voltage(i2c,last?SEC_VOLTAGE_13:SEC_VOLTAGE_18,tuner_type);
        last=(last)? 0 : 1;
      }
      cmd = cmd >> 1;

#ifdef CHECK_DISH_TIMING
      do_gettimeofday(gtod+i);
#endif

      if(i != 8) {
//      mdelay(8);
        set_current_state(TASK_INTERRUPTIBLE);
        schedule_timeout ((HZ*8)/1000);
      }
    }
#ifdef CHECK_DISH_TIMING
    for(i=0;i<10;i++)
      printk("\t%lu\n",gtod[i].tv_usec-first.tv_usec);
#endif
    return 0;
}




Home | Main Index | Thread Index