linux/drivers/media/usb/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                                       enum fe_status *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                                       enum fe_status *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)
  91{
  92        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
  93        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
  94        u8 b[] = { 0x00, 0x00, 0x00, 0x03,
  95                   0x00, 0x00, 0x00, 0x00,
  96                   0x00, 0x00, 0x00, 0x01,
  97                   0x00, 0x00, 0x00, 0xff,
  98                   0x00, 0x00, 0x00, 0xff };
  99
 100        __be32 freq = htonl(p->frequency / 1000);
 101        memcpy(&b[4], &freq, sizeof (u32));
 102        state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
 103
 104        return 0;
 105}
 106
 107static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
 108                                        struct dvb_frontend_tune_settings* fesettings)
 109{
 110                fesettings->min_delay_ms = 1500;
 111                /* Drift compensation makes no sense for DVB-T */
 112                fesettings->step_size = 0;
 113                fesettings->max_drift = 0;
 114                return 0;
 115}
 116
 117static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe)
 118{
 119        struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 120        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
 121
 122        u8 b[] = { 0x00, 0x00, 0x00, 0x01,
 123                   0x00, 0x00, 0x00, 0x00,
 124                   0x00, 0x00, 0x00, 0x01,
 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                   0x00, 0x00, 0x00, 0x00,
 131                   0x00, 0x00, 0x00, 0x00 };
 132        __be32 freq;
 133        __be32 sym_rate;
 134        __be32 band;
 135        __be32 lnb_voltage;
 136
 137        freq = htonl(p->frequency +
 138               (state->hi_band ? LOF_HI : LOF_LO));
 139        memcpy(&b[4], &freq, sizeof(u32));
 140        sym_rate = htonl(p->symbol_rate);
 141        memcpy(&b[12], &sym_rate, sizeof(u32));
 142        band = htonl(state->hi_band ? LOF_HI : LOF_LO);
 143        memcpy(&b[24], &band, sizeof(u32));
 144        lnb_voltage = htonl(state->voltage);
 145        memcpy(&b[28], &lnb_voltage, sizeof(u32));
 146
 147        state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
 148
 149        return 0;
 150}
 151
 152static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
 153{
 154        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
 155        u8 b[] = { 0x00, 0xff, 0x00, 0x00,
 156                   0x00, 0x00, 0x00, 0x00,
 157                   0x00, 0x00 };
 158
 159        if (cmd->msg_len > sizeof(b) - 4)
 160                return -EINVAL;
 161
 162        memcpy(&b[4], cmd->msg, cmd->msg_len);
 163
 164        state->config->send_command(fe, 0x72,
 165                                    sizeof(b) - (6 - cmd->msg_len), b,
 166                                    NULL, NULL);
 167
 168        return 0;
 169}
 170
 171
 172static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend *fe,
 173                                    enum fe_sec_tone_mode tone)
 174{
 175        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
 176
 177        state->hi_band = (SEC_TONE_ON == tone);
 178
 179        return 0;
 180}
 181
 182
 183static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend *fe,
 184                                       enum fe_sec_voltage voltage)
 185{
 186        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
 187
 188        switch (voltage) {
 189        case SEC_VOLTAGE_13:
 190                state->voltage = 13;
 191                break;
 192        case SEC_VOLTAGE_18:
 193                state->voltage = 18;
 194                break;
 195        default:
 196                return -EINVAL;
 197        }
 198
 199        return 0;
 200}
 201
 202static void ttusbdecfe_release(struct dvb_frontend* fe)
 203{
 204        struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
 205        kfree(state);
 206}
 207
 208static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
 209
 210struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
 211{
 212        struct ttusbdecfe_state* state = NULL;
 213
 214        /* allocate memory for the internal state */
 215        state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
 216        if (state == NULL)
 217                return NULL;
 218
 219        /* setup the state */
 220        state->config = config;
 221
 222        /* create dvb_frontend */
 223        memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
 224        state->frontend.demodulator_priv = state;
 225        return &state->frontend;
 226}
 227
 228static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
 229
 230struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
 231{
 232        struct ttusbdecfe_state* state = NULL;
 233
 234        /* allocate memory for the internal state */
 235        state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
 236        if (state == NULL)
 237                return NULL;
 238
 239        /* setup the state */
 240        state->config = config;
 241        state->voltage = 0;
 242        state->hi_band = 0;
 243
 244        /* create dvb_frontend */
 245        memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
 246        state->frontend.demodulator_priv = state;
 247        return &state->frontend;
 248}
 249
 250static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
 251        .delsys = { SYS_DVBT },
 252        .info = {
 253                .name                   = "TechnoTrend/Hauppauge DEC2000-t Frontend",
 254                .frequency_min          = 51000000,
 255                .frequency_max          = 858000000,
 256                .frequency_stepsize     = 62500,
 257                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 258                        FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
 259                        FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
 260                        FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
 261                        FE_CAN_HIERARCHY_AUTO,
 262        },
 263
 264        .release = ttusbdecfe_release,
 265
 266        .set_frontend = ttusbdecfe_dvbt_set_frontend,
 267
 268        .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
 269
 270        .read_status = ttusbdecfe_dvbt_read_status,
 271};
 272
 273static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
 274        .delsys = { SYS_DVBS },
 275        .info = {
 276                .name                   = "TechnoTrend/Hauppauge DEC3000-s Frontend",
 277                .frequency_min          = 950000,
 278                .frequency_max          = 2150000,
 279                .frequency_stepsize     = 125,
 280                .symbol_rate_min        = 1000000,  /* guessed */
 281                .symbol_rate_max        = 45000000, /* guessed */
 282                .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 283                        FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
 284                        FE_CAN_QPSK
 285        },
 286
 287        .release = ttusbdecfe_release,
 288
 289        .set_frontend = ttusbdecfe_dvbs_set_frontend,
 290
 291        .read_status = ttusbdecfe_dvbs_read_status,
 292
 293        .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
 294        .set_voltage = ttusbdecfe_dvbs_set_voltage,
 295        .set_tone = ttusbdecfe_dvbs_set_tone,
 296};
 297
 298MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
 299MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
 300MODULE_LICENSE("GPL");
 301
 302EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
 303EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);
 304