linux/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
<<
>>
Prefs
   1/*
   2 * TTUSB DEC Frontend Driver
   3 *
   4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 *
  20 */
  21
  22#include "dvb_frontend.h"
  23#include "ttusbdecfe.h"
  24
  25
  26#define LOF_HI                  10600000
  27#define LOF_LO                  9750000
  28
  29struct ttusbdecfe_state {
  30
  31        /* configuration settings */
  32        const struct ttusbdecfe_config* config;
  33
  34        struct dvb_frontend frontend;
  35
  36        u8 hi_band;
  37        u8 voltage;
  38};
  39
  40
  41static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe,
  42        fe_status_t *status)
  43{
  44        *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
  45                FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
  46        return 0;
  47}
  48
  49
  50static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe,
  51        fe_status_t *status)
  52{
  53        struct ttusbdecfe_state* state = fe->demodulator_priv;
  54        u8 b[] = { 0x00, 0x00, 0x00, 0x00,
  55                   0x00, 0x00, 0x00, 0x00 };
  56        u8 result[4];
  57        int len, ret;
  58
  59        *status=0;
  60
  61        ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
  62        if(ret)
  63                return ret;
  64
  65        if(len != 4) {
  66                printk(KERN_ERR "%s: unexpected reply\n", __func__);
  67                return -EIO;
  68        }
  69
  70        switch(result[3]) {
  71                case 1:  /* not tuned yet */
  72                case 2:  /* no signal/no lock*/
  73                        break;
  74                case 3:  /* signal found and locked*/
  75                        *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
  76                        FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
  77                        break;
  78                case 4:
  79                        *status = FE_TIMEDOUT;
  80                        break;
  81                default:
  82                        pr_info("%s: returned unknown value: %d\n",
  83                                __func__, result[3]);
  84                        return -EIO;
  85        }
  86
  87        return 0;
  88}
  89
  90static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
  91{
  92        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
  93        u8 b[] = { 0x00, 0x00, 0x00, 0x03,
  94                   0x00, 0x00, 0x00, 0x00,
  95                   0x00, 0x00, 0x00, 0x01,
  96                   0x00, 0x00, 0x00, 0xff,
  97                   0x00, 0x00, 0x00, 0xff };
  98
  99        __be32 freq = htonl(p->frequency / 1000);
 100        memcpy(&b[4], &freq, sizeof (u32));
 101        state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
 102
 103        return 0;
 104}
 105
 106static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
 107                                        struct dvb_frontend_tune_settings* fesettings)
 108{
 109                fesettings->min_delay_ms = 1500;
 110                /* Drift compensation makes no sense for DVB-T */
 111                fesettings->step_size = 0;
 112                fesettings->max_drift = 0;
 113                return 0;
 114}
 115
 116static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
 117{
 118        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
 119
 120        u8 b[] = { 0x00, 0x00, 0x00, 0x01,
 121                   0x00, 0x00, 0x00, 0x00,
 122                   0x00, 0x00, 0x00, 0x01,
 123                   0x00, 0x00, 0x00, 0x00,
 124                   0x00, 0x00, 0x00, 0x00,
 125                   0x00, 0x00, 0x00, 0x00,
 126                   0x00, 0x00, 0x00, 0x00,
 127                   0x00, 0x00, 0x00, 0x00,
 128                   0x00, 0x00, 0x00, 0x00,
 129                   0x00, 0x00, 0x00, 0x00 };
 130        __be32 freq;
 131        __be32 sym_rate;
 132        __be32 band;
 133        __be32 lnb_voltage;
 134
 135        freq = htonl(p->frequency +
 136               (state->hi_band ? LOF_HI : LOF_LO));
 137        memcpy(&b[4], &freq, sizeof(u32));
 138        sym_rate = htonl(p->u.qam.symbol_rate);
 139        memcpy(&b[12], &sym_rate, sizeof(u32));
 140        band = htonl(state->hi_band ? LOF_HI : LOF_LO);
 141        memcpy(&b[24], &band, sizeof(u32));
 142        lnb_voltage = htonl(state->voltage);
 143        memcpy(&b[28], &lnb_voltage, sizeof(u32));
 144
 145        state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
 146
 147        return 0;
 148}
 149
 150static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
 151{
 152        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
 153        u8 b[] = { 0x00, 0xff, 0x00, 0x00,
 154                   0x00, 0x00, 0x00, 0x00,
 155                   0x00, 0x00 };
 156
 157        memcpy(&b[4], cmd->msg, cmd->msg_len);
 158
 159        state->config->send_command(fe, 0x72,
 160                                    sizeof(b) - (6 - cmd->msg_len), b,
 161                                    NULL, NULL);
 162
 163        return 0;
 164}
 165
 166
 167static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 168{
 169        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
 170
 171        state->hi_band = (SEC_TONE_ON == tone);
 172
 173        return 0;
 174}
 175
 176
 177static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
 178{
 179        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
 180
 181        switch (voltage) {
 182        case SEC_VOLTAGE_13:
 183                state->voltage = 13;
 184                break;
 185        case SEC_VOLTAGE_18:
 186                state->voltage = 18;
 187                break;
 188        default:
 189                return -EINVAL;
 190        }
 191
 192        return 0;
 193}
 194
 195static void ttusbdecfe_release(struct dvb_frontend* fe)
 196{
 197        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
 198        kfree(state);
 199}
 200
 201static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
 202
 203struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
 204{
 205        struct ttusbdecfe_state* state = NULL;
 206
 207        /* allocate memory for the internal state */
 208        state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
 209        if (state == NULL)
 210                return NULL;
 211
 212        /* setup the state */
 213        state->config = config;
 214
 215        /* create dvb_frontend */
 216        memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
 217        state->frontend.demodulator_priv = state;
 218        return &state->frontend;
 219}
 220
 221static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
 222
 223struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
 224{
 225        struct ttusbdecfe_state* state = NULL;
 226
 227        /* allocate memory for the internal state */
 228        state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
 229        if (state == NULL)
 230                return NULL;
 231
 232        /* setup the state */
 233        state->config = config;
 234        state->voltage = 0;
 235        state->hi_band = 0;
 236
 237        /* create dvb_frontend */
 238        memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
 239        state->frontend.demodulator_priv = state;
 240        return &state->frontend;
 241}
 242
 243static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
 244
 245        .info = {
 246                .name                   = "TechnoTrend/Hauppauge DEC2000-t Frontend",
 247                .type                   = FE_OFDM,
 248                .frequency_min          = 51000000,
 249                .frequency_max          = 858000000,
 250                .frequency_stepsize     = 62500,
 251                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 252                        FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
 253                        FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
 254                        FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
 255                        FE_CAN_HIERARCHY_AUTO,
 256        },
 257
 258        .release = ttusbdecfe_release,
 259
 260        .set_frontend = ttusbdecfe_dvbt_set_frontend,
 261
 262        .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
 263
 264        .read_status = ttusbdecfe_dvbt_read_status,
 265};
 266
 267static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
 268
 269        .info = {
 270                .name                   = "TechnoTrend/Hauppauge DEC3000-s Frontend",
 271                .type                   = FE_QPSK,
 272                .frequency_min          = 950000,
 273                .frequency_max          = 2150000,
 274                .frequency_stepsize     = 125,
 275                .symbol_rate_min        = 1000000,  /* guessed */
 276                .symbol_rate_max        = 45000000, /* guessed */
 277                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 278                        FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
 279                        FE_CAN_QPSK
 280        },
 281
 282        .release = ttusbdecfe_release,
 283
 284        .set_frontend = ttusbdecfe_dvbs_set_frontend,
 285
 286        .read_status = ttusbdecfe_dvbs_read_status,
 287
 288        .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
 289        .set_voltage = ttusbdecfe_dvbs_set_voltage,
 290        .set_tone = ttusbdecfe_dvbs_set_tone,
 291};
 292
 293MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
 294MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
 295MODULE_LICENSE("GPL");
 296
 297EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
 298EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);
 299