Ticket #1945: dvbdevtree_integration.patch

File dvbdevtree_integration.patch, 58.4 KB (added by yeasah@…, 18 years ago)

Patch containing integration of device tree

  • libs/libmythtv/dvbdiseqc.h

     
    1 /*
    2  *  Copyright (C) Kenneth Aafloy 2003
    3  * 
    4  *  Copyright notice is in dvbdiseqc.cpp of the MythTV project.
    5  */
    6 
    7 #ifndef DVBDISEQC_H
    8 #define DVBDISEQC_H
    9 
    10 #include "pthread.h"
    11 #include "qsqldatabase.h"
    12 #include "tv_rec.h"
    13 #include "dvbtypes.h"
    14 #include <linux/dvb/frontend.h>
    15 
    16 #define DISEQC_SHORT_WAIT 15*1000
    17 #define DISEQC_LONG_WAIT 100*1000
    18 
    19 class DVBDiSEqC
    20 {
    21 public:
    22     DVBDiSEqC(int cardnum, int fd_frontend);
    23     ~DVBDiSEqC();
    24 
    25     bool Set(DVBTuning& tuning, bool reset, bool& havetuned);
    26     bool DiseqcReset();
    27 
    28 private:
    29     int cardnum;
    30     int fd_frontend;
    31     DVBTuning prev_tuning;
    32     int repeat;
    33 
    34    
    35     bool SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd);
    36     bool SendDiSEqCMessage(dvb_diseqc_master_cmd &cmd);
    37    
    38     bool ToneVoltageLnb(DVBTuning& tuning, bool reset, bool& havetuned);
    39     bool ToneSwitch(DVBTuning& tuning, bool reset, bool& havetuned);
    40     bool LegacyDishSwitch(DVBTuning& tuning, bool reset, bool& havetuned);
    41     bool Diseqc1xSwitch(DVBTuning& tuning, bool reset, bool& havetuned,
    42                         uint ports);
    43     bool PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned);
    44     bool PositionerStore(DVBTuning& tuning);
    45     bool PositionerStopMovement();
    46     bool PositionerStoreEastLimit();
    47     bool PositionerStoreWestLimit();
    48     bool PositionerDisableLimits();   
    49     bool PositionerDriveEast(int timestep);
    50     bool PositionerDriveWest(int timestep);
    51     bool PositionerGotoAngular(DVBTuning& tuning, bool reset,
    52                                bool& havetuned);
    53 
    54     // Still need to be written
    55     bool Positioner_Status();
    56 
    57     enum diseqc_cmd_bytes {
    58         FRAME               = 0x0,
    59         ADDRESS             = 0x1,
    60         COMMAND             = 0x2,
    61         DATA_1              = 0x3,
    62         DATA_2              = 0x4,
    63         DATA_3              = 0x5
    64     };
    65 
    66     enum diseqc_frame_byte {
    67         CMD_FIRST           = 0xe0,
    68         CMD_REPEAT          = 0xe1,
    69         CMD_REPLY_FIRST     = 0xe2,
    70         CMD_REPLY_REPEAT    = 0xe3,
    71         REPLY_OK            = 0xe4,
    72         REPLY_NOSUPPORT     = 0xe5,
    73         REPLY_CRCERR_RPT    = 0xe6,
    74         REPLY_CMDERR_RPT    = 0xe7
    75     };
    76        
    77     enum diseqc_address {
    78         MASTER_TO_ALL        = 0x00,
    79         MASTER_TO_LSS        = 0x10,
    80         MASTER_TO_LNB        = 0x11,
    81         MASTER_TO_SWITCH     = 0x14,
    82         MASTER_TO_POSITIONER = 0x31
    83     };
    84 
    85 
    86     enum diseqc_commands {
    87         RESET               = 0x00,
    88         CLR_RESET           = 0x01,
    89         STANDBY             = 0x02,
    90         POWERON             = 0x03,
    91         SET_LO              = 0x20,
    92         SET_VR              = 0x21,
    93         SET_POS_A           = 0x22,
    94         SET_SO_A            = 0x23,
    95         SET_HI              = 0x24,
    96         SET_HL              = 0x25,
    97         SET_POS_B           = 0x26,
    98         SET_SO_B            = 0x27,
    99         WRITE_N0            = 0x38,
    100         WRITE_N1            = 0x39,
    101         WRITE_N2            = 0x3A,
    102         WRITE_N3            = 0x3B,
    103         READ_LNB_LOF_LO     = 0x52,
    104         READ_LNB_LOF_HI     = 0x53,
    105 
    106         HALT                = 0x60,
    107         LIMITS_OFF          = 0x63,
    108         POS_STAT            = 0x64,
    109         LIMIT_E             = 0x66,
    110         LIMIT_W             = 0x67,
    111         DRIVE_E             = 0x68,
    112         DRIVE_W             = 0x69,
    113         STORE               = 0x6A,
    114         GOTO                = 0x6B,
    115         GOTO_ANGULAR        = 0x6E
    116     };
    117 
    118 };
    119 
    120 #endif // DVBDISEQC_H
  • libs/libmythtv/dvbdiseqc.cpp

     
    1 /*
    2  *  Class DVBDiSEqC
    3  *
    4  *  Copyright (C) Kenneth Aafloy 2003
    5  *
    6  *  Description:
    7  *
    8  *  Author(s):
    9  *      Taylor Jacob (rtjacob at earthlink.net)
    10  *          - Finished Implimenting Petri's DiSEqC 1.0 - 1.1 code
    11  *          - DiSEqC 1.2 Positioner control
    12  *      Petri Nykanen
    13  *          - DiSEqC 1.0 - 1.1.
    14  *      Kenneth Aafloy (ke-aa at frisurf.no)
    15  *          - Initial framework.
    16  *
    17  *   This program is free software; you can redistribute it and/or modify
    18  *   it under the terms of the GNU General Public License as published by
    19  *   the Free Software Foundation; either version 2 of the License, or
    20  *   (at your option) any later version.
    21  *
    22  *   This program is distributed in the hope that it will be useful,
    23  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
    24  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    25  *   GNU General Public License for more details.
    26  *
    27  *   You should have received a copy of the GNU General Public License
    28  *   along with this program; if not, write to the Free Software
    29  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    30  */
    31 
    32 #include <iostream>
    33 #include <cmath>
    34 
    35 #include "pthread.h"
    36 #include "qsqldatabase.h"
    37 
    38 #include "mythcontext.h"
    39 #include "tv_rec.h"
    40 #include "cardutil.h"
    41 
    42 #include "dvbtypes.h"
    43 #include "dvbdiseqc.h"
    44 
    45 #define TO_RADS (M_PI / 180.0)
    46 #define TO_DEC (180.0 / M_PI)
    47 
    48 #define LOC QString("DiSEqC(%1): ").arg(cardnum)
    49 #define LOC_ERR QString("DiSEqC(%1) Error: ").arg(cardnum)
    50 
    51 DVBDiSEqC::DVBDiSEqC(int _cardnum, int _fd_frontend):
    52     cardnum(_cardnum), fd_frontend(_fd_frontend)
    53 {
    54 
    55     // Number of repeats for DiSEqC 1.1 devices
    56     repeat = 1;
    57 }
    58 
    59 DVBDiSEqC::~DVBDiSEqC()
    60 {
    61 }
    62 
    63 bool DVBDiSEqC::Set(DVBTuning& tuning, bool reset, bool& havetuned)
    64 {
    65     switch (tuning.diseqc_type)
    66     {
    67         case DISEQC_MINI_2:
    68             if (!ToneSwitch(tuning, reset, havetuned))
    69                 return false;
    70             // fall through
    71         case DISEQC_SINGLE:
    72             if (!ToneVoltageLnb(tuning, reset, havetuned))
    73                 return false;
    74             break;
    75         case DISEQC_SWITCH_2_1_0: // 2 Way v1.0
    76         case DISEQC_SWITCH_2_1_1: // 2 Way v1.1
    77             if (!Diseqc1xSwitch(tuning, reset, havetuned, 2))
    78                 return false;
    79             break;
    80         case DISEQC_SWITCH_4_1_0: // 4 Way v1.0
    81         case DISEQC_SWITCH_4_1_1: // 4 Way v1.1
    82             if (!Diseqc1xSwitch(tuning, reset, havetuned, 4))
    83                 return false;
    84             break;
    85         case DISEQC_POSITIONER_1_2: // 1.2 Positioner (HH Motor)
    86             if (!PositionerGoto(tuning,reset,havetuned))
    87                 return false;
    88             break;
    89         case DISEQC_POSITIONER_X: // 1.3 Positioner (HH Motor with USALS)
    90             if (!PositionerGotoAngular(tuning,reset,havetuned))
    91                 return false;
    92             break;
    93         case DISEQC_POSITIONER_1_2_SWITCH_2: // 10 Way v1.1 or v2.1
    94             if (!Diseqc1xSwitch(tuning, reset, havetuned, 10))
    95                 return false;
    96             break;
    97         case DISEQC_SW21: // Dish Network legacy switch SW21
    98         case DISEQC_SW64: // Dish Network legacy switch SW64
    99             if (!LegacyDishSwitch(tuning, reset, havetuned))
    100                 return false;
    101             break;
    102  
    103         default:
    104             VERBOSE(VB_IMPORTANT, LOC_ERR + "Unsupported DiSEqC type("
    105                     <<tuning.diseqc_type<<")");
    106     }
    107    
    108     return true;
    109 }
    110 
    111 bool DVBDiSEqC::LegacyDishSwitch(DVBTuning &tuning, bool reset,
    112                                  bool &havetuned)
    113 {
    114     VERBOSE(VB_CHANNEL, LOC + "Legacy Dish Switch: " +
    115             QString("Port %1").arg(tuning.diseqc_port));
    116 
    117     if (reset ||
    118         (prev_tuning.diseqc_port != tuning.diseqc_port ||
    119          prev_tuning.tone        != tuning.tone        ||
    120          prev_tuning.voltage     != tuning.voltage))
    121     {
    122         uint8_t cmd = 0x00;
    123 
    124         if (DISEQC_SW21 == tuning.diseqc_type)
    125             cmd = (tuning.diseqc_port) ? 0x66 : 0x34;
    126         else if (DISEQC_SW64 == tuning.diseqc_type)
    127         {
    128             if (tuning.diseqc_port == 0)
    129                 cmd = (tuning.voltage == SEC_VOLTAGE_13) ? 0x39 : 0x1A;
    130             else if (tuning.diseqc_port == 1)
    131                 cmd = (tuning.voltage == SEC_VOLTAGE_13) ? 0x4B : 0x5C;
    132             else
    133                 cmd = (tuning.voltage == SEC_VOLTAGE_13) ? 0x0D : 0x2E;
    134         }
    135 
    136         if (tuning.voltage == SEC_VOLTAGE_18)
    137             cmd |= 0x80;
    138 
    139 #ifdef FE_DISHNETWORK_SEND_LEGACY_CMD
    140         if (ioctl(fd_frontend, FE_DISHNETWORK_SEND_LEGACY_CMD, cmd) <0)
    141         {
    142             VERBOSE(VB_IMPORTANT, LOC_ERR + "Legacy Dish Switch: "
    143                     "Sending init command failed." + ENO);
    144             return false;
    145         }
    146 #else
    147         VERBOSE(VB_IMPORTANT, LOC_ERR + "Legacy Dish Switch: " +
    148                 "Linux kernel does not support this switch.");
    149 #endif
    150 
    151         usleep(DISEQC_SHORT_WAIT);
    152 
    153         prev_tuning.diseqc_port = tuning.diseqc_port;
    154         prev_tuning.tone        = tuning.tone;
    155         prev_tuning.voltage     = tuning.voltage;
    156         havetuned = true;
    157     }
    158     return true;
    159 }
    160 
    161 /*****************************************************************************
    162                         Backward Compatible Methods
    163  ****************************************************************************/
    164 
    165 bool DVBDiSEqC::ToneVoltageLnb(DVBTuning& tuning, bool reset, bool& havetuned)
    166 {
    167     VERBOSE(VB_CHANNEL, LOC + QString("Setting LNB: %1 %2")
    168             .arg(tuning.tone==SEC_TONE_ON?"Tone ON":"Tone OFF")
    169             .arg(tuning.voltage==SEC_VOLTAGE_13?"13V":"18V"));
    170 
    171     if (prev_tuning.tone != tuning.tone || reset)
    172     {
    173         if (ioctl(fd_frontend, FE_SET_TONE, tuning.tone) < 0)
    174         {
    175             VERBOSE(VB_IMPORTANT, LOC_ERR +
    176                     "Setting Tone mode failed." + ENO);
    177             return false;
    178         }
    179 
    180         prev_tuning.tone = tuning.tone;
    181     }
    182 
    183     usleep(DISEQC_SHORT_WAIT);
    184 
    185     if (prev_tuning.voltage != tuning.voltage || reset)
    186     {
    187         if (ioctl(fd_frontend, FE_SET_VOLTAGE, tuning.voltage) < 0)
    188         {
    189             VERBOSE(VB_IMPORTANT, LOC_ERR +
    190                     "Setting Polarization failed." + ENO);
    191             return false;
    192         }
    193 
    194         prev_tuning.voltage = tuning.voltage;
    195     }
    196 
    197     havetuned |= ((prev_tuning.voltage == tuning.voltage) &&
    198                   (prev_tuning.tone == tuning.tone));
    199 
    200     return true;
    201 }
    202 
    203 bool DVBDiSEqC::ToneSwitch(DVBTuning& tuning, bool reset, bool& havetuned)
    204 {
    205     VERBOSE(VB_CHANNEL, LOC + QString("Tone Switch - Port %1/2")
    206             .arg(tuning.diseqc_port));
    207 
    208     if (prev_tuning.diseqc_port != tuning.diseqc_port || reset)
    209     {
    210         if (tuning.diseqc_port > 2)
    211             VERBOSE(VB_IMPORTANT, LOC_ERR +
    212                     "Tone Switches only support two ports.");
    213 
    214         if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST,
    215                   (tuning.diseqc_port == 1 ? SEC_MINI_A : SEC_MINI_B )) < 0)
    216         {
    217             VERBOSE(VB_IMPORTANT, LOC_ERR +
    218                     "Setting Tone Switch failed." + ENO);
    219             return false;
    220         }
    221 
    222         prev_tuning.diseqc_port = tuning.diseqc_port;
    223     }
    224 
    225     havetuned |= (prev_tuning.diseqc_port == tuning.diseqc_port);
    226 
    227     return true;
    228 }
    229 
    230 /*****************************************************************************
    231                     Diseqc 1.x Compatible Methods
    232  ****************************************************************************/
    233 
    234 bool DVBDiSEqC::SendDiSEqCMessage(DVBTuning& tuning, dvb_diseqc_master_cmd &cmd)
    235 {
    236     // Turn off tone burst
    237     if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1)
    238     {
    239         VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);
    240         return false;
    241     }
    242 
    243 /*
    244    Old version of the code set the voltage to 13V everytime.
    245    After looking at the EutelSat specs I saw no reason that
    246    this was done. I have tested this with my DiSEqC switch
    247    and all is fine.
    248 */
    249 
    250     if (ioctl(fd_frontend, FE_SET_VOLTAGE, tuning.voltage) == -1)
    251     {
    252         VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_VOLTAGE failed" + ENO);
    253         return false;
    254     }   
    255 
    256     usleep(DISEQC_SHORT_WAIT);
    257 
    258     VERBOSE(VB_CHANNEL, LOC + QString("Sending 1.0 Command: %1 %2 %3 %4")
    259             .arg(cmd.msg[0], 2, 16)
    260             .arg(cmd.msg[1], 2, 16)
    261             .arg(cmd.msg[2], 2, 16)
    262             .arg(cmd.msg[3], 2, 16));
    263 
    264     if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1)
    265     {
    266         VERBOSE(VB_IMPORTANT, LOC_ERR +
    267                 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
    268         return false;
    269     }
    270 
    271     usleep(DISEQC_SHORT_WAIT);
    272 
    273     // Check to see if its a 1.1 or 1.2 device.
    274     // If so repeat the message repeats times.
    275     if ((tuning.diseqc_type == DISEQC_SWITCH_2_1_1)   ||
    276         (tuning.diseqc_type == DISEQC_SWITCH_4_1_1)   ||
    277         (tuning.diseqc_type == DISEQC_POSITIONER_1_2) ||
    278         (tuning.diseqc_type == DISEQC_POSITIONER_X))
    279     {
    280 
    281         int repeats = repeat;
    282         while (repeats--)
    283         {
    284 
    285             if (tuning.diseqc_type == DISEQC_POSITIONER_X)
    286             {
    287                 VERBOSE(VB_CHANNEL, LOC +
    288                         QString("Sending 1.3 Repeat Command: %1 %2 %3 %4 %5")
    289                         .arg(cmd.msg[0],2,16)
    290                         .arg(cmd.msg[1],2,16)
    291                         .arg(cmd.msg[2],2,16)
    292                         .arg(cmd.msg[3],2,16)
    293                         .arg(cmd.msg[4],2,16));
    294             }
    295             else
    296             {
    297                 VERBOSE(VB_CHANNEL, LOC +
    298                         QString("Sending 1.1/1.2 Repeat Command: %1 %2 %3 %4")
    299                         .arg(cmd.msg[0],2,16)
    300                         .arg(cmd.msg[1],2,16)
    301                         .arg(cmd.msg[2],2,16)
    302                         .arg(cmd.msg[3],2,16));
    303             }
    304 
    305             cmd.msg[0] = CMD_REPEAT;     
    306             if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1)
    307             {
    308                 VERBOSE(VB_IMPORTANT, LOC_ERR +
    309                         "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
    310                 return false;
    311             }
    312             usleep(DISEQC_SHORT_WAIT);
    313      
    314             cmd.msg[0] = CMD_FIRST;     
    315             if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1)
    316             {
    317                 VERBOSE(VB_IMPORTANT, LOC_ERR +
    318                         "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
    319                 return false;
    320             }
    321             usleep(DISEQC_SHORT_WAIT);
    322         }
    323     }
    324 
    325     if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A ) == -1)
    326     {
    327         VERBOSE(VB_IMPORTANT, LOC_ERR +
    328                 "FE_DISEQC_SEND_BURST failed" + ENO);
    329         return false;
    330     }
    331 
    332     usleep(DISEQC_SHORT_WAIT);
    333 
    334     if (ioctl(fd_frontend, FE_SET_TONE, tuning.tone) == -1)
    335     {
    336         VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);
    337         return false;
    338     }
    339 
    340     return true;
    341 }
    342 
    343 
    344 bool DVBDiSEqC::SendDiSEqCMessage(dvb_diseqc_master_cmd &cmd)
    345 {
    346     // Turn off tone burst
    347     if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) == -1)
    348     {
    349         VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_SET_TONE failed" + ENO);
    350         return false;
    351     }
    352 
    353     usleep(DISEQC_SHORT_WAIT);
    354 
    355     VERBOSE(VB_CHANNEL, LOC + QString("Sending 1.0 Command: %1 %2 %3 %4")
    356             .arg(cmd.msg[0], 2, 16)
    357             .arg(cmd.msg[1], 2, 16)
    358             .arg(cmd.msg[2], 2, 16)
    359             .arg(cmd.msg[3], 2, 16));
    360 
    361     if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1)
    362     {
    363         VERBOSE(VB_IMPORTANT, LOC_ERR +
    364                 "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
    365         return false;
    366     }
    367 
    368     usleep(DISEQC_SHORT_WAIT);
    369  
    370     int repeats = repeat;
    371     while (repeats--)
    372     {
    373         VERBOSE(VB_CHANNEL, LOC +
    374                 QString("Sending 1.1/1.2/1.3 Repeat Command: %1 %2 %3 %4")
    375                 .arg(cmd.msg[0], 2, 16)
    376                 .arg(cmd.msg[1], 2, 16)
    377                 .arg(cmd.msg[2], 2, 16)
    378                 .arg(cmd.msg[3], 2, 16));
    379 
    380         cmd.msg[0] = CMD_REPEAT;     
    381         if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1)
    382         {
    383             VERBOSE(VB_IMPORTANT, LOC_ERR +
    384                     "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
    385             return false;
    386         }
    387         usleep(DISEQC_SHORT_WAIT);
    388    
    389         cmd.msg[0] = CMD_FIRST;     
    390         if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1)
    391         {
    392             VERBOSE(VB_IMPORTANT, LOC_ERR +
    393                     "FE_DISEQC_SEND_MASTER_CMD failed" + ENO);
    394             return false;
    395         }
    396         usleep(DISEQC_SHORT_WAIT);
    397     }
    398 
    399     if (ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A ) == -1)
    400     {
    401         VERBOSE(VB_IMPORTANT, LOC_ERR + "FE_DISEQC_SEND_BURST failed" + ENO);
    402         return false;
    403     }
    404 
    405     return true;
    406 }
    407 
    408 bool DVBDiSEqC::Diseqc1xSwitch(DVBTuning& tuning, bool reset,
    409                                bool& havetuned, uint ports)
    410 {
    411     if (reset)
    412     {
    413         if (!DiseqcReset())
    414         {
    415             VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
    416             return false;
    417         }
    418     }
    419 
    420     VERBOSE(VB_CHANNEL, LOC +
    421             QString("1.1 Switch (%1 ports) - Port %2 - %3 %4")
    422             .arg(ports)
    423             .arg(tuning.diseqc_port)
    424             .arg(tuning.tone==SEC_TONE_ON?"Tone ON":"Tone OFF")
    425             .arg(tuning.voltage==SEC_VOLTAGE_13?"13V":"18V"));
    426 
    427     if ((prev_tuning.diseqc_port != tuning.diseqc_port  ||
    428          prev_tuning.tone != tuning.tone                ||
    429          prev_tuning.voltage != tuning.voltage        ) || reset)
    430     {
    431         dvb_diseqc_master_cmd cmd =
    432             {{CMD_FIRST, MASTER_TO_LSS, WRITE_N1, 0xf0, 0x00, 0x00}, 4};
    433 
    434         if (tuning.diseqc_port >= ports )
    435         {
    436             VERBOSE(VB_IMPORTANT, LOC_ERR + "Unsupported switch");
    437             return false;
    438         }
    439 
    440         switch (ports)
    441         {
    442             case 10:
    443                 cmd.msg[COMMAND] = WRITE_N1;
    444                 cmd.msg[DATA_1] = 0xF0 | (tuning.diseqc_port & 0x0F);
    445                 break;
    446             case 4:
    447             case 2:
    448                 cmd.msg[COMMAND] = WRITE_N0;
    449                 cmd.msg[DATA_1] =
    450                     0xF0 |
    451                     (((tuning.diseqc_port) * 4) & 0x0F)          |
    452                     ((tuning.voltage == SEC_VOLTAGE_18) ? 2 : 0) |
    453                     ((tuning.tone == SEC_TONE_ON) ? 1 : 0);
    454                 break;
    455             default:
    456                 VERBOSE(VB_IMPORTANT, LOC_ERR +
    457                         "Unsupported number of ports for DiSEqC 1.1 Switch");
    458         }
    459 
    460         if (!SendDiSEqCMessage(tuning,cmd))
    461         {
    462             VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
    463             return false;
    464         }
    465 
    466         prev_tuning.diseqc_port = tuning.diseqc_port;
    467         prev_tuning.tone = tuning.tone;
    468         prev_tuning.voltage = tuning.voltage;
    469         havetuned = true;
    470 
    471     }
    472 
    473     havetuned |=
    474         (prev_tuning.diseqc_port == tuning.diseqc_port) &&
    475         (prev_tuning.voltage     == tuning.voltage)     &&
    476         (prev_tuning.tone        == tuning.tone);
    477 
    478     return true;
    479 }
    480 
    481 bool DVBDiSEqC::DiseqcReset()
    482 {
    483     struct dvb_diseqc_master_cmd reset_cmd =
    484         {{CMD_FIRST, MASTER_TO_LSS, RESET, 0x00, 0x00}, 3};
    485  
    486     struct dvb_diseqc_master_cmd init_cmd =
    487         {{CMD_FIRST, MASTER_TO_LSS, POWERON, 0x00, 0x00}, 3};
    488 
    489     if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0)
    490     {
    491         VERBOSE(VB_IMPORTANT, LOC_ERR +
    492                 "Setup: Sending init command failed." + ENO);
    493         return false;
    494     }
    495     usleep(DISEQC_LONG_WAIT);
    496 
    497     if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &reset_cmd) <0)
    498     {
    499         VERBOSE(VB_IMPORTANT, LOC_ERR +
    500                 "Setup: Sending reset command failed." + ENO);
    501         return false;
    502     }
    503     usleep(DISEQC_LONG_WAIT);
    504 
    505     if (ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &init_cmd) <0)
    506     {
    507         VERBOSE(VB_IMPORTANT, LOC_ERR +
    508                 "Setup: Sending init command failed." + ENO);
    509         return false;
    510     }
    511     usleep(DISEQC_LONG_WAIT);
    512 
    513     return true;
    514 }
    515 
    516 /*****************************************************************************
    517                             Positioner Control
    518  *****************************************************************************/
    519 
    520 bool DVBDiSEqC::PositionerDriveEast(int timestep)
    521 {
    522     if (!DiseqcReset())
    523     {
    524         VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
    525         return false;
    526     }
    527 
    528     dvb_diseqc_master_cmd cmd =
    529         {{CMD_FIRST, MASTER_TO_POSITIONER, DRIVE_E, timestep ,0x00,0x00}, 4};
    530 
    531     if (!SendDiSEqCMessage(cmd))
    532     {
    533         VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
    534         return false;
    535     }
    536    
    537     return true;
    538 }
    539 
    540 bool DVBDiSEqC::PositionerDriveWest(int timestep)
    541 {
    542     if (!DiseqcReset())
    543     {
    544         VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
    545         return false;
    546     }
    547 
    548     dvb_diseqc_master_cmd cmd =
    549         {{CMD_FIRST, MASTER_TO_POSITIONER, DRIVE_W, timestep ,0x00,0x00}, 4};
    550 
    551     if (!SendDiSEqCMessage(cmd))
    552     {
    553         VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
    554         return false;
    555     }
    556 
    557     return true;
    558 }
    559 
    560 bool DVBDiSEqC::PositionerGoto(DVBTuning& tuning, bool reset, bool& havetuned)
    561 {
    562     // A reset seems to be required for my positioner to work consistently
    563     VERBOSE(VB_CHANNEL, LOC + QString("1.2 Motor - Goto Stored Position %1")
    564             .arg(tuning.diseqc_port));
    565 
    566     if ((prev_tuning.diseqc_port != tuning.diseqc_port ||
    567          prev_tuning.tone != tuning.tone ||
    568          prev_tuning.voltage != tuning.voltage) || reset)
    569     {
    570         if (!DiseqcReset())
    571         {
    572             VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
    573             return false;
    574         }
    575        
    576         dvb_diseqc_master_cmd cmd =
    577             {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO, tuning.diseqc_port,
    578               0x00, 0x00}, 4};
    579 
    580         if (!SendDiSEqCMessage(tuning,cmd))
    581         {
    582             VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
    583             return false;
    584         }
    585 
    586         prev_tuning.diseqc_port = tuning.diseqc_port;
    587         prev_tuning.tone = tuning.tone;
    588         prev_tuning.voltage = tuning.voltage;
    589     }
    590 
    591     havetuned |=
    592         (prev_tuning.diseqc_port == tuning.diseqc_port) &&
    593         (prev_tuning.voltage     == tuning.voltage)     &&
    594         (prev_tuning.tone        == tuning.tone);
    595 
    596     return true;
    597 }
    598 
    599 bool DVBDiSEqC::PositionerStore(DVBTuning& tuning)
    600 {
    601     if (!DiseqcReset())
    602     {
    603         VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
    604         return false;
    605     }
    606 
    607     VERBOSE(VB_CHANNEL, LOC + QString("1.2 Motor - Store Stored Position %1")
    608             .arg(tuning.diseqc_port));
    609 
    610     dvb_diseqc_master_cmd cmd =
    611         {{CMD_FIRST, MASTER_TO_POSITIONER, STORE, tuning.diseqc_port , 0x00,
    612           0x00}, 4};
    613 
    614     if (!SendDiSEqCMessage(cmd))
    615     {
    616         VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
    617         return false;
    618     }
    619 
    620     return true;
    621 }
    622 
    623 bool DVBDiSEqC::PositionerStoreEastLimit()
    624 {
    625     if (!DiseqcReset())
    626     {
    627         VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
    628         return false;
    629     }
    630 
    631     dvb_diseqc_master_cmd cmd =
    632         {{CMD_FIRST, MASTER_TO_POSITIONER, LIMIT_E, 0x00,0x00,0x00}, 3};
    633 
    634     if (!SendDiSEqCMessage(cmd))
    635     {
    636         VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
    637         return false;
    638     }
    639 
    640     return true;
    641 }
    642 
    643 bool DVBDiSEqC::PositionerStoreWestLimit()
    644 {
    645     if (!DiseqcReset())
    646     {
    647         VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
    648         return false;
    649     }
    650 
    651     dvb_diseqc_master_cmd cmd =
    652         {{CMD_FIRST, MASTER_TO_POSITIONER, LIMIT_W, 0x00,0x00,0x00}, 3};
    653 
    654     if (!SendDiSEqCMessage(cmd))
    655     {
    656         VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
    657         return false;
    658     }
    659 
    660     return true;
    661 }
    662 
    663 bool DVBDiSEqC::PositionerStopMovement()
    664 {
    665     if (!DiseqcReset())
    666     {
    667         VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
    668         return false;
    669     }
    670 
    671     dvb_diseqc_master_cmd cmd =
    672         {{CMD_FIRST, MASTER_TO_POSITIONER, HALT, 0x00,0x00,0x00}, 3};
    673 
    674     if (!SendDiSEqCMessage(cmd))
    675     {
    676         VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
    677         return false;
    678     }
    679     return true;
    680 
    681 }
    682 
    683 bool DVBDiSEqC::Positioner_Status()
    684 {
    685     // Not sure if this function is possible without being DiSEqC >= v2
    686     // Someone with a DVB card that supports v2 cards will need to help me out
    687     // here
    688     return false;
    689 }
    690 
    691 bool DVBDiSEqC::PositionerDisableLimits()
    692 {
    693     if (!DiseqcReset())
    694     {
    695         VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
    696         return false;
    697     }
    698 
    699     dvb_diseqc_master_cmd cmd =
    700         {{CMD_FIRST, MASTER_TO_POSITIONER, LIMITS_OFF, 0x00,0x00,0x00}, 3};
    701 
    702     if (!SendDiSEqCMessage(cmd))
    703     {
    704         VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
    705         return false;
    706     }
    707 
    708     return true;
    709 }
    710 
    711 /*****************************************************************************
    712                                 Diseqc v1.3 (Goto X)
    713  ****************************************************************************/
    714 
    715 bool DVBDiSEqC::PositionerGotoAngular(DVBTuning& tuning, bool reset,
    716                                       bool& havetuned)
    717 {
    718     // TODO: Send information here to FE saying motor is moving and
    719     //       to expect a longer than average tuning delay
    720     if (prev_tuning.diseqc_pos != tuning.diseqc_pos)
    721         VERBOSE(VB_CHANNEL, LOC + "DiSEqC Motor Moving");
    722 
    723     if (!DiseqcReset())
    724     {
    725         VERBOSE(VB_IMPORTANT, LOC_ERR + "DiseqcReset() failed");
    726         return false;
    727     }
    728 
    729     VERBOSE(VB_CHANNEL, LOC + QString("1.3 Motor - Goto Angular Position %1")
    730             .arg(tuning.diseqc_pos));
    731 
    732     // Equation lifted from VDR rotor plugin by
    733     // Thomas Bergwinkl <Thomas.Bergwinkl@t-online.de>
    734 
    735     // Earth Station Latitude and Longitude in radians
    736     double P  = gContext->GetSetting("Latitude",  "").toFloat() * TO_RADS;
    737     double Ue = gContext->GetSetting("Longitude", "").toFloat() * TO_RADS;
    738 
    739     // Satellite Longitude in radians
    740     double Us = tuning.diseqc_pos * TO_RADS;
    741 
    742     double az      = M_PI + atan( tan(Us - Ue) / sin(P) );
    743     double x       = acos( cos(Us - Ue) * cos(P) );
    744     double el      = atan( (cos(x) - 0.1513) / sin(x) );
    745     double tmp_a   = -cos(el) * sin(az);
    746     double tmp_b   = (sin(el) * cos(P)) - (cos(el) * sin(P) * cos(az));
    747     double azimuth = atan(tmp_a / tmp_b) * TO_DEC;
    748 
    749     // Bytes sent to motor
    750     // cmd1 high nibble is 1110b/0xE0 for east or 1101b/0xD0 for west
    751     // cmd1 low  nibble is angle / 16
    752     // cmd2 high nibble is angle % 16
    753     // cmd2 low  nibble is (angle * 16) % 16
    754     uint az16 = (unsigned int) (abs(azimuth) * 16.0);
    755     uint cmd1 = ((azimuth > 0.0) ? 0xE0 : 0xD0) | ((az16 >> 8) & 0x0f);
    756     uint cmd2 = (az16 & 0xff);
    757 
    758     dvb_diseqc_master_cmd cmd =
    759         {{CMD_FIRST, MASTER_TO_POSITIONER, GOTO_ANGULAR, cmd1, cmd2, 0x00}, 5};
    760  
    761     if ((prev_tuning.diseqc_port != tuning.diseqc_port  ||
    762          prev_tuning.tone        != tuning.tone         ||
    763          prev_tuning.diseqc_pos  != tuning.diseqc_pos   ||
    764          prev_tuning.voltage     != tuning.voltage    ) || reset)
    765     {
    766         if (!SendDiSEqCMessage(tuning, cmd))
    767         {
    768             VERBOSE(VB_IMPORTANT, LOC_ERR + "Setting DiSEqC failed.");
    769             return false;
    770         }
    771 
    772         prev_tuning.diseqc_port = tuning.diseqc_port;
    773         prev_tuning.diseqc_pos  = tuning.diseqc_pos;
    774         prev_tuning.tone        = tuning.tone;
    775         prev_tuning.voltage     = tuning.voltage;
    776     }
    777 
    778     havetuned |=
    779         (prev_tuning.diseqc_port == tuning.diseqc_port) &&
    780         (prev_tuning.diseqc_pos  == tuning.diseqc_pos)  &&
    781         (prev_tuning.voltage     == tuning.voltage)     &&
    782         (prev_tuning.tone        == tuning.tone);
    783 
    784     return true;
    785 }
  • libs/libmythtv/dvbtypes.cpp

     
    416416    }
    417417}
    418418
     419char DVBTuning::PolarityChar() const
     420{
     421    return polariz;
     422}
     423
    419424char DVBTuning::TransmissionModeChar() const
    420425{
    421426    switch (params.u.ofdm.transmission_mode)
     
    539544    return coderate(params.u.qam.fec_inner);
    540545}
    541546
     547QString DVBTuning::QPSKInnerFECString() const
     548{
     549    return coderate(params.u.qpsk.fec_inner);
     550}
     551
    542552QString DVBTuning::GuardIntervalString() const
    543553{
    544554    //Guard Interval
     
    584594        msg = QString("Frequency: %1 Symbol Rate: %2 Pol: %3 Inv: %4")
    585595            .arg(Frequency())
    586596            .arg(QPSKSymbolRate())
    587             .arg((voltage == SEC_VOLTAGE_13) ? "V/R" : "H/L")
     597            .arg(PolarityChar())
    588598            .arg(InversionString());
    589599    }
    590600    else if (FE_QAM == type)
     
    676686bool DVBTuning::parseDVBS2(
    677687    const QString& frequency,   const QString& inversion,
    678688    const QString& symbol_rate, const QString& fec_inner,
    679     const QString& pol,         const QString& _diseqc_type,
    680     const QString& _diseqc_port,
    681     const QString& _diseqc_pos,
    682     const QString& _lnb_lof_switch,
    683     const QString& _lnb_lof_hi,
    684     const QString& _lnb_lof_lo,
     689    const QString& pol,
    685690    const QString &modulation)
    686691{
    687692    bool ok = true;
     
    702707        return false;
    703708    }
    704709
    705     voltage = parsePolarity(pol, ok);
    706     if (SEC_VOLTAGE_OFF == voltage)
    707     {
    708         VERBOSE(VB_IMPORTANT, LOC_ERR + "Invalid polarization, aborting.");
    709         return false;
    710     }
     710    if(!pol.isEmpty())
     711        polariz = QChar(pol[0]).lower();
    711712
    712713    p.fec_inner = parseCodeRate(fec_inner, ok);
    713714
    714715    p.modulation = parseModulation(modulation, ok);
    715     diseqc_type = _diseqc_type.toInt();
    716     diseqc_port = _diseqc_port.toInt();
    717     diseqc_pos  = _diseqc_pos.toFloat();
    718     lnb_lof_switch = _lnb_lof_switch.toInt();
    719     lnb_lof_hi  = _lnb_lof_hi.toInt();
    720     lnb_lof_lo  = _lnb_lof_lo.toInt();
    721716    return true;
    722717}
    723718#endif
    724719
    725 // TODO: Add in DiseqcPos when diseqc class supports it
    726720bool DVBTuning::parseQPSK(const QString& frequency,   const QString& inversion,
    727721                          const QString& symbol_rate, const QString& fec_inner,
    728                           const QString& pol,         const QString& _diseqc_type,
    729                           const QString& _diseqc_port,
    730                           const QString& _diseqc_pos,
    731                           const QString& _lnb_lof_switch,
    732                           const QString& _lnb_lof_hi,
    733                           const QString& _lnb_lof_lo)
     722                          const QString& pol)
    734723{
    735724    bool ok = true;
    736725
     
    753742        return false;
    754743    }
    755744
    756     voltage = parsePolarity(pol, ok);
    757     if (SEC_VOLTAGE_OFF == voltage)
    758     {
    759         VERBOSE(VB_IMPORTANT, LOC_ERR + "Invalid polarization, aborting.");
     745    if(!pol.isEmpty())
     746        polariz = QChar(pol[0]).lower();
    760747
    761         return false;
    762     }
    763 
    764748    p.fec_inner = parseCodeRate(fec_inner, ok);
    765749
    766     diseqc_type = _diseqc_type.toInt();
    767     diseqc_port = _diseqc_port.toInt();
    768     diseqc_pos  = _diseqc_pos.toFloat();
    769     lnb_lof_switch = _lnb_lof_switch.toInt();
    770     lnb_lof_hi  = _lnb_lof_hi.toInt();
    771     lnb_lof_lo  = _lnb_lof_lo.toInt();
    772750    return true;
    773751}
    774752
     
    823801    return BANDWIDTH_AUTO;
    824802}
    825803
    826 fe_sec_voltage DVBTuning::parsePolarity(const QString &pol, bool &ok)
    827 {
    828     char polarity = QChar(pol[0]).lower();
    829     ok = true;
    830     switch (polarity)
    831     {
    832         case 'v':
    833         case 'r': return SEC_VOLTAGE_13;
    834         case 'h':
    835         case 'l': return SEC_VOLTAGE_18;
    836         default: return SEC_VOLTAGE_OFF;
    837     }
    838 }
    839 
    840804fe_guard_interval DVBTuning::parseGuardInterval(const QString &gi, bool &ok)
    841805{
    842806    QString guard_interval = gi.lower();
     
    1015979{
    1016980    switch (coderate)
    1017981    {
    1018         case FEC_NONE: return "None";
     982        case FEC_NONE: return "none";
    1019983        case FEC_1_2:  return "1/2";
    1020984        case FEC_2_3:  return "2/3";
    1021985        case FEC_3_4:  return "3/4";
     
    1024988        case FEC_6_7:  return "6/7";
    1025989        case FEC_7_8:  return "7/8";
    1026990        case FEC_8_9:  return "8/9";
    1027         default:       return "Auto";
     991        default:       return "auto";
    1028992    }
    1029993}
    1030994
  • libs/libmythtv/dvbtypes.h

     
    318318{
    319319  public:
    320320    DVBTuning()
    321       : voltage(SEC_VOLTAGE_OFF), tone(SEC_TONE_OFF),
    322         diseqc_type(0), diseqc_port(0), diseqc_pos(0.0f),
    323         lnb_lof_switch(0), lnb_lof_hi(0), lnb_lof_lo(0)
     321        : polariz('v')
    324322    {
    325323        bzero(&params, sizeof(dvb_fe_params));
    326324    }
    327325
    328326    struct dvb_fe_params params;
    329     fe_sec_voltage_t    voltage;
    330     fe_sec_tone_mode_t  tone;
    331     unsigned int        diseqc_type;
    332     unsigned int        diseqc_port;
    333     float               diseqc_pos;
    334     unsigned int        lnb_lof_switch;
    335     unsigned int        lnb_lof_hi;
    336     unsigned int        lnb_lof_lo;
     327    char                 polariz;
    337328
    338329    bool equalQPSK(const DVBTuning& other, uint range = 0) const
    339330        { return equal_qpsk(params, other.params, range);  }
     
    348339
    349340    // Helper functions to get the paramaters as DB friendly strings
    350341    char InversionChar() const;
     342    char PolarityChar() const;
    351343    char TransmissionModeChar() const;
    352344    char BandwidthChar() const;
    353345    char HierarchyChar() const;
     
    356348
    357349    // Helper functions to parse params from DB friendly strings
    358350    static fe_bandwidth      parseBandwidth(    const QString&, bool &ok);
    359     static fe_sec_voltage    parsePolarity(     const QString&, bool &ok);
    360351    static fe_guard_interval parseGuardInterval(const QString&, bool &ok);
    361352    static fe_transmit_mode  parseTransmission( const QString&, bool &ok);
    362353    static fe_hierarchy      parseHierarchy(    const QString&, bool &ok);
     
    375366    QString HPCodeRateString() const;
    376367    QString LPCodeRateString() const;
    377368    QString QAMInnerFECString() const;
     369    QString QPSKInnerFECString() const;
    378370    QString ModulationString() const;
    379371    QString ConstellationString() const;
    380372    QString HierarchyString() const;
     
    390382
    391383    bool parseQPSK(const QString& frequency,      const QString& inversion,
    392384                   const QString& symbol_rate,    const QString& fec_inner,
    393                    const QString& pol,            const QString& diseqc_type,
    394                    const QString& diseqc_port,    const QString& diseqc_pos,
    395                    const QString& lnb_lof_switch, const QString& lnb_lof_hi,
    396                    const QString& lnb_lof_lo);
     385                   const QString& pol);
    397386
    398387    bool parseQAM(const QString& frequency,       const QString& inversion,
    399388                  const QString& symbol_rate,     const QString& fec_inner,
     
    405394    uint DVBS2SymbolRate() const { return params.u.qpsk2.symbol_rate; }
    406395    bool parseDVBS2(const QString& frequency,      const QString& inversion,
    407396                   const QString& symbol_rate,    const QString& fec_inner,
    408                    const QString& pol,            const QString& diseqc_type,
    409                    const QString& diseqc_port,    const QString& diseqc_pos,
    410                    const QString& lnb_lof_switch, const QString& lnb_lof_hi,
    411                    const QString& lnb_lof_lo,     const QString& modulation);
     397                   const QString& pol);
    412398#endif
    413399};
    414400
  • libs/libmythtv/channelutil.h

     
    145145    static QString GetServiceName(int chanid);
    146146    static int     GetSourceID(int mplexid);
    147147    static QString GetInputName(int sourceid);
     148    static int     GetInputID(int sourceid, int cardid);
    148149    static QString GetDTVPrivateType(uint networkid, const QString &key,
    149150                                     const QString sitype = "dvb");
    150151
  • libs/libmythtv/channelutil.cpp

     
    231231            // DVB specific
    232232            tsid,                 netid,
    233233            cd.SymbolRateHz(),    -1,
    234             QChar(cd.PolarizationString()[0]), -1,
     234            QChar(cd.PolarizationString()[0]), 'a',
    235235            -1,
    236236            cd.FECInnerString(),  QString::null,
    237237            -1,                   QString::null,
     
    670670    return inputname;
    671671}
    672672
     673int ChannelUtil::GetInputID(int source_id, int card_id)
     674{
     675    int input_id = -1;
     676
     677    MSqlQuery query(MSqlQuery::InitCon());
     678    query.prepare("SELECT cardinputid"
     679                  " FROM cardinput"
     680                  " WHERE sourceid = :SOURCEID"
     681                  " AND cardid = :CARDID");
     682    query.bindValue(":SOURCEID", source_id);
     683    query.bindValue(":CARDID", card_id);
     684
     685    if (query.exec() && query.isActive() && query.next())
     686        input_id = query.value(0).toInt();
     687
     688    return input_id;
     689}
     690
    673691QString ChannelUtil::GetChannelValueStr(const QString &channel_field,
    674692                                        uint           cardid,
    675693                                        const QString &input,
  • libs/libmythtv/dvbchannel.h

     
    1919
    2020#ifdef USING_DVB
    2121#include "dvbtypes.h"
     22#include "dvbdevtree.h"
    2223#else // if !USING_DVB
    2324typedef int fe_type_t;
    2425typedef int fe_modulation_t;
    2526typedef int fe_code_rate_t;
    2627typedef int DVBTuning;
     28typedef void DVBDevRotor;
    2729typedef struct { QString name; fe_type_t type; } dvb_frontend_info;
    2830#endif //!USING_DVB
    2931
    3032class TVRec;
    3133class DVBCam;
    3234class DVBRecorder;
    33 class DVBDiSEqC;
    3435
    3536class DVBChannel : public ChannelBase
    3637{
     
    6465    bool SwitchToInput(const QString &inputname, const QString &chan);
    6566    bool SwitchToInput(int newcapchannel, bool setstarting);
    6667    bool SetChannelByString(const QString &chan);
    67     bool Tune(const DVBTuning &tuning, bool force_reset = false);
    68     bool TuneMultiplex(uint mplexid);
    6968
     69    // Tuning
     70    bool Tune(const DVBTuning &tuning,
     71              bool force_reset = false,
     72              int sourceid = -1,
     73              bool same_input = false);
     74    bool TuneMultiplex(uint mplexid, int sourceid = -1);
     75    bool Retune();
     76
    7077    bool GetTuningParams(DVBTuning &tuning) const;
    7178
    7279    // PID caching
    7380    void SaveCachedPids(const pid_cache_t&) const;
    7481    void GetCachedPids(pid_cache_t&) const;
    7582
     83    // Returns rotor object (or NULL)
     84    const DVBDevRotor* GetRotor() const;
     85
     86    // If false, card needs retuning when lock is lost
     87    bool CanRecover() const;
     88
     89    // Amount of time since last tuning request
     90    int ElapsedSinceTune() const;
     91
    7692  private:
    7793    int  GetChanID(void) const;
    7894    bool GetTransportOptions(int mplexid);
     
    85101    bool ParseTuningParams(
    86102        fe_type_t type,
    87103        QString frequency,    QString inversion,      QString symbolrate,
    88         QString fec,          QString polarity,       QString dvb_diseqc_type,
    89         QString diseqc_port,  QString diseqc_pos,     QString lnb_lof_switch,
    90         QString lnb_lof_hi,   QString lnb_lof_lo,     QString _sistandard,
     104        QString fec,          QString polarity,       QString _sistandard,
    91105        QString hp_code_rate, QString lp_code_rate,   QString constellation,
    92106        QString trans_mode,   QString guard_interval, QString hierarchy,
    93107        QString modulation,   QString bandwidth,      QString _input_id);
    94108
    95109  private:
     110#ifdef USING_DVB
    96111    // Data
    97     DVBDiSEqC        *diseqc; ///< Used to send commands to external devices
     112    DVBDev            dvbdev;
     113    DVBDevTree*       devtree;
     114    DVBDevSettings    devset;
     115#endif
    98116    DVBCam           *dvbcam; ///< Used to decrypt encrypted streams
    99117
    100118    // Tuning State
     
    113131    int               cardnum;     ///< DVB Card number
    114132    bool              has_crc_bug; ///< true iff our driver munges PMT
    115133    int               nextInputID; ///< Signal an input change
     134
     135    QTime             tune_time;
     136    QMutex            tune_lock;
    116137};
    117138
    118139#endif
  • libs/libmythtv/dvbchannel.cpp

     
    5252#include "mythdbcon.h"
    5353#include "tv_rec.h"
    5454#include "cardutil.h"
     55#include "channelutil.h"
    5556
    5657#include "dvbtypes.h"
    5758#include "dvbchannel.h"
    5859#include "dvbrecorder.h"
    59 #include "dvbdiseqc.h"
     60#include "dvbdevtree.h"
    6061#include "dvbcam.h"
    6162
    62 static uint tuned_frequency(const DVBTuning&, fe_type_t, fe_sec_tone_mode_t *);
    6363static void drain_dvb_events(int fd);
    6464static bool wait_for_backend(int fd, int timeout_ms);
    65 static bool handle_diseq(const DVBTuning&, DVBDiSEqC*, bool reset);
    6665
    6766#define LOC QString("DVBChan(%1): ").arg(cardnum)
    6867#define LOC_WARN QString("DVBChan(%1) Warning: ").arg(cardnum)
     
    7675DVBChannel::DVBChannel(int aCardNum, TVRec *parent)
    7776    : ChannelBase(parent),
    7877      // Helper classes
    79       diseqc(NULL),                 dvbcam(NULL),
     78      devtree(NULL),
     79      dvbcam(NULL),
    8080      // Tuning
    8181      tuning_delay(0),              sigmon_delay(25),
    8282      first_tune(true),
     
    9393DVBChannel::~DVBChannel()
    9494{
    9595    Close();
    96     if (dvbcam)
    97     {
    98         delete dvbcam;
    99         dvbcam = NULL;
    100     }
     96    delete dvbcam;
     97    dvbcam = NULL;
    10198}
    10299
    103100void DVBChannel::Close()
     
    106103
    107104    if (fd_frontend >= 0)
    108105    {
     106        if(devtree)
     107            devtree->Close();
     108
    109109        close(fd_frontend);
    110110        fd_frontend = -1;
    111111
    112112        dvbcam->Stop();
    113 
    114         if (diseqc)
    115         {
    116             delete diseqc;
    117             diseqc = NULL;
    118         }
    119113    }
    120114}
    121115
     
    189183    if (info.type == FE_QPSK)
    190184#endif
    191185    {
    192         if (ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF) < 0)
    193         {
    194             VERBOSE(VB_GENERAL, LOC_WARN +
    195                     "Initial Tone setting failed." + ENO);
    196         }
    197 
    198         if (ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13) < 0)
    199         {
    200             VERBOSE(VB_GENERAL, LOC_WARN +
    201                     "Initial Voltage setting failed." + ENO);
    202         }
    203 
    204         if (diseqc == NULL)
    205         {
    206             diseqc = new DVBDiSEqC(cardnum, fd_frontend);
    207             diseqc->DiseqcReset();
    208         }
     186        devtree = dvbdev.FindTree(GetCardID());
     187        if(devtree)
     188            devtree->Open(fd_frontend);
    209189    }
    210190   
    211191    dvbcam->Start();
     
    228208 *
    229209 *   mplexid is how the db indexes each transport
    230210 */
    231 bool DVBChannel::TuneMultiplex(uint mplexid)
     211bool DVBChannel::TuneMultiplex(uint mplexid, int sourceid)
    232212{
    233213    if (!GetTransportOptions(mplexid))
    234214        return false;
     
    236216    CheckOptions();
    237217    VERBOSE(VB_CHANNEL, LOC + cur_tuning.toString(info.type));
    238218
    239     if (!Tune(cur_tuning))
     219    if (!Tune(cur_tuning, false, sourceid))
    240220        return false;
    241221
    242222    return true;
     
    406386    // Query for our DVBTuning params
    407387    query.prepare(
    408388        "SELECT frequency,         inversion,      symbolrate, "
    409         "       fec,               polarity,       dvb_diseqc_type, "
    410         "       diseqc_port,       diseqc_pos,     lnb_lof_switch, "
    411         "       lnb_lof_hi,        lnb_lof_lo,     sistandard, "
     389        "       fec,               polarity,       sistandard, "
    412390        "       hp_code_rate,      lp_code_rate,   constellation, "
    413391        "       transmission_mode, guard_interval, hierarchy, "
    414392        "       modulation,        bandwidth,      cardinputid "
     
    444422        query.value(8).toString(),  query.value(9).toString(),
    445423        query.value(10).toString(), query.value(11).toString(),
    446424        query.value(12).toString(), query.value(13).toString(),
    447         query.value(14).toString(), query.value(15).toString(),
    448         query.value(16).toString(), query.value(17).toString(),
    449         query.value(18).toString(), query.value(19).toString(),
    450         query.value(20).toString());
     425        query.value(14).toString());
    451426}
    452427
    453428bool DVBChannel::ParseTuningParams(
    454429    fe_type_t type,
    455430    QString frequency,    QString inversion,      QString symbolrate,
    456     QString fec,          QString polarity,       QString dvb_diseqc_type,
    457     QString diseqc_port,  QString diseqc_pos,     QString lnb_lof_switch,
    458     QString lnb_lof_hi,   QString lnb_lof_lo,     QString _sistandard,
     431    QString fec,          QString polarity,       QString _sistandard,
    459432    QString hp_code_rate, QString lp_code_rate,   QString constellation,
    460433    QString trans_mode,   QString guard_interval, QString hierarchy,
    461434    QString modulation,   QString bandwidth,      QString _input_id)
     
    465438
    466439    if (FE_QPSK == type)
    467440        return cur_tuning.parseQPSK(
    468             frequency,       inversion,     symbolrate,   fec,   polarity,
    469             dvb_diseqc_type, diseqc_port,   diseqc_pos,
    470             lnb_lof_switch,  lnb_lof_hi,    lnb_lof_lo);
     441            frequency,       inversion,     symbolrate,   fec,   polarity);
    471442    else if (FE_QAM == type)
    472443        return cur_tuning.parseQAM(
    473444            frequency,       inversion,     symbolrate,   fec,   modulation);
     
    506477        t.params.inversion = INVERSION_OFF;
    507478    }
    508479
    509     uint frequency = tuned_frequency(t, info.type, NULL);
     480    uint frequency = t.params.frequency;
     481    if(devtree)
     482    {
     483        DVBDevLnb* lnb = devtree->FindLNB(devset);
     484        if(lnb)
     485            frequency = lnb->GetIF(devset, t);
     486    }
    510487
    511488    if ((info.frequency_min > 0 && info.frequency_max > 0) &&
    512489       (frequency < info.frequency_min || frequency > info.frequency_max))
     
    697674 *  \param channel     Info on transport to tune to
    698675 *  \param force_reset If true, frequency tuning is done
    699676 *                     even if it should not be needed.
     677 *  \param source_id   Optional, forces specific sourceid (for diseqc setup).
     678 *  \param same_input  Optional, doesn't change input (for retuning).
    700679 *  \return true on success, false on failure
    701680 */
    702 bool DVBChannel::Tune(const DVBTuning &tuning, bool force_reset)
     681bool DVBChannel::Tune(const DVBTuning &tuning,
     682                      bool force_reset,
     683                      int source_id,
     684                      bool same_input)
    703685{
    704     bool reset = (force_reset || first_tune);
    705     bool has_diseq = (FE_QPSK == info.type) && diseqc;
    706     struct dvb_fe_params params = tuning.params;
     686    QMutexLocker lock(&tune_lock);
    707687
     688    bool reset = (force_reset || first_tune);
     689    bool is_dvbs = (FE_QPSK == info.type);
    708690#ifdef FE_GET_EXTENDED_INFO
    709     has_diseq |= (FE_DVB_S2 == info.type) && diseqc;
     691    is_dvbs |= (FE_DVB_S2 == info.type);
    710692#endif // FE_GET_EXTENDED_INFO
     693    bool has_diseqc = (devtree != NULL);
     694    struct dvb_fe_params params = tuning.params;
    711695
     696    tune_time.start();
     697
     698    if(is_dvbs && !has_diseqc)
     699    {
     700        VERBOSE(VB_IMPORTANT, LOC_ERR + "DVB-S needs device tree");
     701        return false;
     702    }
     703
    712704    if (fd_frontend < 0)
    713705    {
    714706        VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): Card not open!");
     
    719711    // Remove any events in queue before tuning.
    720712    drain_dvb_events(fd_frontend);
    721713
    722     // Send DisEq commands to external hardware if we need to.
    723     if (has_diseq && !handle_diseq(tuning, diseqc, reset))
     714    // send DVB-S setup
     715    if (is_dvbs)
    724716    {
    725         VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): "
    726                 "Failed to transmit DisEq commands");
     717        // configure for new input
     718        if(!same_input)
     719        {
     720            devset.Load(source_id == -1 ? nextInputID :
     721                        ChannelUtil::GetInputID(source_id, GetCardID()));
     722        }
     723           
     724        // execute diseqc commands
     725        if(!devtree->Execute(devset, tuning))
     726        {
     727            VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): "
     728                    "Failed to setup DiSEqC devices");
     729            return false;
     730        }
    727731
    728         return false;
     732        // retrieve actual intermediate frequency
     733        DVBDevLnb* lnb = devtree->FindLNB(devset);
     734        if(!lnb)
     735        {
     736            VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): "
     737                    "No LNB for this configuration");
     738            return false;
     739        }
     740        params.frequency = lnb->GetIF(devset, tuning);
     741
     742        // if card can auto-FEC, use it -- sometimes NITs are inaccurate
     743        if(info.caps & FE_CAN_FEC_AUTO)
     744            params.u.qpsk.fec_inner = FEC_AUTO;
    729745    }
    730746
    731747    VERBOSE(VB_CHANNEL, LOC + "Old Params: " +
     
    733749            "\n\t\t\t" + LOC + "New Params: " +
    734750            tuning.toString(info.type));
    735751
    736     if (reset || !prev_tuning.equal(info.type, tuning, 500000))
    737     {
    738         // Adjust for Satelite recievers which offset the frequency.
    739         params.frequency = tuned_frequency(tuning, info.type, NULL);
     752    // DVB-S is in kHz, other DVB is in Hz
     753    int freq_mult = is_dvbs ? 1 : 1000;
     754    const char* suffix = is_dvbs ? "kHz" : "Hz";
    740755
     756    if (reset || !prev_tuning.equal(info.type, tuning, 500 * freq_mult))
     757    {
     758        VERBOSE(VB_CHANNEL, LOC + QString("Tune(): Tuning to %1%2")
     759                .arg(params.frequency)
     760                .arg(suffix));
    741761#ifdef FE_GET_EXTENDED_INFO
    742762        if (info.type == FE_DVB_S2)
    743763        {
     
    774794    return true;
    775795}
    776796
     797bool DVBChannel::Retune()
     798{
     799    return Tune(prev_tuning, true, -1, true);
     800}
     801
    777802/** \fn DVBChannel::GetTuningParams(DVBTuning& tuning) const
    778803 *  \brief Fetches DVBTuning params from driver
    779804 *  \return true on success, false on failure
     
    843868        ChannelBase::GetCachedPids(chanid, pid_cache);
    844869}
    845870
     871const DVBDevRotor* DVBChannel::GetRotor() const
     872{
     873    const DVBDevRotor* rotor = devtree ? devtree->FindRotor(devset) : NULL;
     874    return rotor;
     875}
     876
     877bool DVBChannel::CanRecover() const
     878{
     879    return info.caps & FE_CAN_RECOVER;
     880}
     881
     882int DVBChannel::ElapsedSinceTune() const
     883{
     884    return first_tune ? 0 : tune_time.elapsed();
     885}
     886
    846887/** \fn drain_dvb_events(int)
    847888 *  \brief Reads all the events off the queue, so we can use select
    848889 *         in wait_for_backend(int,int).
     
    853894    while (ioctl(fd, FE_GET_EVENT, &event) == 0);
    854895}
    855896
    856 static uint tuned_frequency(const DVBTuning &tuning, fe_type_t type,
    857                             fe_sec_tone_mode_t *p_tone)
    858 {
    859 #ifdef FE_GET_EXTENDED_INFO
    860     if (FE_QPSK != type && FE_DVB_S2 != type)
    861         return tuning.Frequency();
    862 #else
    863     if (FE_QPSK != type)
    864         return tuning.Frequency();
    865 #endif
    866 
    867     uint freq   = tuning.Frequency();
    868     bool tone   = freq >= tuning.lnb_lof_switch;
    869     uint lnb_hi = (uint) abs((int)freq - (int)tuning.lnb_lof_hi);
    870     uint lnb_lo = (uint) abs((int)freq - (int)tuning.lnb_lof_lo);
    871 
    872     if (p_tone)
    873         *p_tone = (tone) ? SEC_TONE_ON : SEC_TONE_OFF;
    874 
    875     return (tone) ? lnb_hi : lnb_lo;
    876 }
    877 
    878897/** \fn wait_for_backend(int,int)
    879898 *  \brief Waits for backend to get tune message.
    880899 *
     
    923942            .arg(toString(status)));
    924943    return true;
    925944}
    926 
    927 /** \fn handle_diseq(const DVBTuning&, DVBDiSEqC*, bool)
    928  *  \brief Sends DisEq commands to external hardware.
    929  *
    930  */
    931 static bool handle_diseq(const DVBTuning &ct, DVBDiSEqC *diseqc, bool reset)
    932 {
    933     if (!diseqc)
    934         return false;
    935 
    936     bool tuned  = false;
    937     DVBTuning t = ct;
    938     t.params.frequency = tuned_frequency(ct, FE_QPSK, &t.tone);
    939 
    940     for (uint i = 0; i < 64 && !tuned; i++)
    941         if (!diseqc->Set(t, reset, tuned))
    942             return false;
    943 
    944     // Wait 10 ms, recommended by Marcus Metzler, see #1552
    945     usleep(10 * 1000);
    946 
    947     return true;
    948 }
  • libs/libmythtv/siscan.cpp

     
    376376                                  bool wait_until_complete)
    377377{
    378378    const DVBStreamData &dsd = (const DVBStreamData &)(*sd);
    379     if (wait_until_complete && !dsd.HasCachedSDT() && !dsd.HasCachedAllNIT())
     379    if (wait_until_complete && (!dsd.HasCachedSDT() || !dsd.HasCachedAllNIT()))
    380380        return;
    381381
    382382    emit ServiceScanUpdateText(tr("Updating Services"));
     
    619619    // Tune to multiplex
    620620    if (GetDVBChannel())
    621621    {
     622        // always wait for rotor to finish
     623        GetDVBSignalMonitor()->AddFlags(kDVBSigMon_WaitForPos);
     624
    622625        if (item.mplexid > 0)
    623626        {
    624             ok = GetDVBChannel()->TuneMultiplex(item.mplexid);
     627            ok = GetDVBChannel()->TuneMultiplex(item.mplexid, item.SourceID);
    625628        }
    626629        else
    627630        {
    628631            DVBTuning tuning = item.tuning;
    629632            tuning.params.frequency = freq;
    630             ok = GetDVBChannel()->Tune(tuning, true);
     633            ok = GetDVBChannel()->Tune(tuning, true, item.SourceID);
    631634        }
    632635    }
    633636#endif // USING_DVB
     
    827830        ok = tuning.parseQPSK(
    828831            startChan["frequency"],   startChan["inversion"],
    829832            startChan["symbolrate"],  startChan["fec"],
    830             startChan["polarity"],
    831             startChan["diseqc_type"], startChan["diseqc_port"],
    832             startChan["diseqc_pos"],  startChan["lnb_lof_switch"],
    833             startChan["lnb_lof_hi"],  startChan["lnb_lof_lo"]);
     833            startChan["polarity"]);
    834834    }
    835835    else if (std == "dvb" && mod.left(3) == "qam")
    836836    {
     
    13401340                QString::null /*inner FEC*/,tuning.ConstellationDB(),
    13411341                tuning.HierarchyChar(),     tuning.HPCodeRateString(),
    13421342                tuning.LPCodeRateString(),  tuning.GuardIntervalString());
     1343        else if (FE_QPSK == GetDVBChannel()->GetCardType())
     1344            mplexid = ChannelUtil::CreateMultiplex(
     1345                (*transport).SourceID,      (*transport).standard,
     1346                tuning.Frequency(),         (*transport).ModulationDB(),
     1347                sm->GetDetectedTransportID(),
     1348                sm->GetDetectedNetworkID(),
     1349                tuning.QPSKSymbolRate(),    -1,
     1350                tuning.PolarityChar(),      tuning.InversionChar(),
     1351                -1,
     1352                tuning.QPSKInnerFECString(),QString::null,
     1353                -1,                         QString::null,
     1354                QString::null,              QString::null);
     1355        else if (FE_QAM == GetDVBChannel()->GetCardType())
     1356            mplexid = ChannelUtil::CreateMultiplex(
     1357                (*transport).SourceID,      (*transport).standard,
     1358                tuning.Frequency(),         tuning.ModulationString(),
     1359                sm->GetDetectedTransportID(),
     1360                sm->GetDetectedNetworkID(),
     1361                tuning.QAMSymbolRate(),     -1,
     1362                -1,                         -1,
     1363                -1,
     1364                tuning.QAMInnerFECString(), QString::null,
     1365                -1,                         QString::null,
     1366                QString::null,              QString::null);
    13431367        else
    13441368            mplexid = ChannelUtil::CreateMultiplex(
    13451369                (*transport).SourceID,      (*transport).standard,
  • libs/libmythtv/scanwizardscanner.cpp

     
    269269    popupProgress = NULL;
    270270}
    271271
    272 static bool get_diseqc(uint cardid, uint sourceid,
    273                        QMap<QString,QString> &startChan)
    274 {
    275     // SQL code to get the disqec paramters HERE
    276     MSqlQuery query(MSqlQuery::InitCon());
    277     query.prepare(
    278         "SELECT dvb_diseqc_type, diseqc_port,  diseqc_pos, "
    279         "       lnb_lof_switch,  lnb_lof_hi,   lnb_lof_lo "
    280         "FROM cardinput, capturecard "
    281         "WHERE cardinput.cardid   = capturecard.cardid AND "
    282         "      cardinput.cardid   = :CARDID            AND "
    283         "      cardinput.sourceid = :SOURCEID ");
    284     query.bindValue(":CARDID",   cardid);
    285     query.bindValue(":SOURCEID", sourceid);
    286 
    287     if (!query.exec() || !query.isActive())
    288     {
    289         MythContext::DBError("ScanWizardScanner::scan()", query);
    290         return false;
    291     }
    292 
    293     if (query.next())
    294     {
    295         startChan["diseqc_type"]    = query.value(0).toString();
    296         startChan["diseqc_port"]    = query.value(1).toString();
    297         startChan["diseqc_pos"]     = query.value(2).toString();
    298         startChan["lnb_lof_switch"] = query.value(3).toString();
    299         startChan["lnb_lof_hi"]     = query.value(4).toString();
    300         startChan["lnb_lof_lo"]     = query.value(5).toString();
    301         return true;
    302     }
    303 
    304     return false;
    305 }
    306 
    307272// full scan of existing transports broken
    308273// existing transport scan broken
    309274void ScanWizardScanner::scan()
     
    375340        startChan["modulation"] = "qpsk";
    376341        startChan["polarity"]   = pane->polarity();
    377342
    378         nit_scan_parse_failed = !get_diseqc(cardid, nVideoSource, startChan);
    379 
    380343#ifdef USING_DVB
    381344        if (!nit_scan_parse_failed)
    382345        {
     
    384347            nit_scan_parse_failed = !tuning.parseQPSK(
    385348                startChan["frequency"],   startChan["inversion"],
    386349                startChan["symbolrate"],  startChan["fec"],
    387                 startChan["polarity"],
    388                 startChan["diseqc_type"], startChan["diseqc_port"],
    389                 startChan["diseqc_pos"],  startChan["lnb_lof_switch"],
    390                 startChan["lnb_lof_hi"],  startChan["lnb_lof_lo"]);
     350                startChan["polarity"]);
    391351        }
    392352#endif // USING_DVB
    393353    }
  • libs/libmythtv/dbcheck.cpp

     
    88
    99#include "mythcontext.h"
    1010#include "mythdbcon.h"
     11#ifdef USING_DVB
     12#include "dvbdevtree.h"
     13#endif
    1114
    1215/// This is the DB schema version expected by the running MythTV instance.
    1316const QString currentDatabaseVersion = "1143";
     
    419422 */
    420423bool UpgradeTVDatabaseSchema(void)
    421424{
     425#ifdef USING_DVB
     426    // TODO: The code in DatabaseDiseqcUpgrade (just sequence of SQL queries)
     427    // should be versioned and added to the database creation/upgrade functions as
     428    // normal. DatabaseDiseqcImport() should be called as part of that upgrade
     429    // process as well.
     430    if(DatabaseDiseqcUpgrade())
     431        DatabaseDiseqcImport();
     432#endif
     433
    422434    QString dbver = gContext->GetSetting("DBSchemaVer");
    423435
    424436    VERBOSE(VB_IMPORTANT, QString("Current Schema Version: %1").arg(dbver));