linux/drivers/media/dvb/frontends/dvb-pll.c
<<
>>
Prefs
   1/*
   2 * descriptions + helper functions for simple dvb plls.
   3 *
   4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
   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#include <linux/module.h>
  22#include <linux/dvb/frontend.h>
  23#include <asm/types.h>
  24
  25#include "dvb-pll.h"
  26
  27struct dvb_pll_priv {
  28        /* pll number */
  29        int nr;
  30
  31        /* i2c details */
  32        int pll_i2c_address;
  33        struct i2c_adapter *i2c;
  34
  35        /* the PLL descriptor */
  36        struct dvb_pll_desc *pll_desc;
  37
  38        /* cached frequency/bandwidth */
  39        u32 frequency;
  40        u32 bandwidth;
  41};
  42
  43#define DVB_PLL_MAX 64
  44
  45static unsigned int dvb_pll_devcount;
  46
  47static int debug;
  48module_param(debug, int, 0644);
  49MODULE_PARM_DESC(debug, "enable verbose debug messages");
  50
  51static unsigned int id[DVB_PLL_MAX] =
  52        { [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED };
  53module_param_array(id, int, NULL, 0644);
  54MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)");
  55
  56/* ----------------------------------------------------------- */
  57
  58struct dvb_pll_desc {
  59        char *name;
  60        u32  min;
  61        u32  max;
  62        u32  iffreq;
  63        void (*set)(struct dvb_frontend *fe, u8 *buf,
  64                    const struct dvb_frontend_parameters *params);
  65        u8   *initdata;
  66        u8   *sleepdata;
  67        int  count;
  68        struct {
  69                u32 limit;
  70                u32 stepsize;
  71                u8  config;
  72                u8  cb;
  73        } entries[12];
  74};
  75
  76/* ----------------------------------------------------------- */
  77/* descriptions                                                */
  78
  79static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
  80        .name  = "Thomson dtt7579",
  81        .min   = 177000000,
  82        .max   = 858000000,
  83        .iffreq= 36166667,
  84        .sleepdata = (u8[]){ 2, 0xb4, 0x03 },
  85        .count = 4,
  86        .entries = {
  87                {  443250000, 166667, 0xb4, 0x02 },
  88                {  542000000, 166667, 0xb4, 0x08 },
  89                {  771000000, 166667, 0xbc, 0x08 },
  90                {  999999999, 166667, 0xf4, 0x08 },
  91        },
  92};
  93
  94static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf,
  95                               const struct dvb_frontend_parameters *params)
  96{
  97        if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth)
  98                buf[3] |= 0x10;
  99}
 100
 101static struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
 102        .name  = "Thomson dtt759x",
 103        .min   = 177000000,
 104        .max   = 896000000,
 105        .set   = thomson_dtt759x_bw,
 106        .iffreq= 36166667,
 107        .sleepdata = (u8[]){ 2, 0x84, 0x03 },
 108        .count = 5,
 109        .entries = {
 110                {  264000000, 166667, 0xb4, 0x02 },
 111                {  470000000, 166667, 0xbc, 0x02 },
 112                {  735000000, 166667, 0xbc, 0x08 },
 113                {  835000000, 166667, 0xf4, 0x08 },
 114                {  999999999, 166667, 0xfc, 0x08 },
 115        },
 116};
 117
 118static struct dvb_pll_desc dvb_pll_lg_z201 = {
 119        .name  = "LG z201",
 120        .min   = 174000000,
 121        .max   = 862000000,
 122        .iffreq= 36166667,
 123        .sleepdata = (u8[]){ 2, 0xbc, 0x03 },
 124        .count = 5,
 125        .entries = {
 126                {  157500000, 166667, 0xbc, 0x01 },
 127                {  443250000, 166667, 0xbc, 0x02 },
 128                {  542000000, 166667, 0xbc, 0x04 },
 129                {  830000000, 166667, 0xf4, 0x04 },
 130                {  999999999, 166667, 0xfc, 0x04 },
 131        },
 132};
 133
 134static struct dvb_pll_desc dvb_pll_unknown_1 = {
 135        .name  = "unknown 1", /* used by dntv live dvb-t */
 136        .min   = 174000000,
 137        .max   = 862000000,
 138        .iffreq= 36166667,
 139        .count = 9,
 140        .entries = {
 141                {  150000000, 166667, 0xb4, 0x01 },
 142                {  173000000, 166667, 0xbc, 0x01 },
 143                {  250000000, 166667, 0xb4, 0x02 },
 144                {  400000000, 166667, 0xbc, 0x02 },
 145                {  420000000, 166667, 0xf4, 0x02 },
 146                {  470000000, 166667, 0xfc, 0x02 },
 147                {  600000000, 166667, 0xbc, 0x08 },
 148                {  730000000, 166667, 0xf4, 0x08 },
 149                {  999999999, 166667, 0xfc, 0x08 },
 150        },
 151};
 152
 153/* Infineon TUA6010XS
 154 * used in Thomson Cable Tuner
 155 */
 156static struct dvb_pll_desc dvb_pll_tua6010xs = {
 157        .name  = "Infineon TUA6010XS",
 158        .min   =  44250000,
 159        .max   = 858000000,
 160        .iffreq= 36125000,
 161        .count = 3,
 162        .entries = {
 163                {  115750000, 62500, 0x8e, 0x03 },
 164                {  403250000, 62500, 0x8e, 0x06 },
 165                {  999999999, 62500, 0x8e, 0x85 },
 166        },
 167};
 168
 169/* Panasonic env57h1xd5 (some Philips PLL ?) */
 170static struct dvb_pll_desc dvb_pll_env57h1xd5 = {
 171        .name  = "Panasonic ENV57H1XD5",
 172        .min   =  44250000,
 173        .max   = 858000000,
 174        .iffreq= 36125000,
 175        .count = 4,
 176        .entries = {
 177                {  153000000, 166667, 0xc2, 0x41 },
 178                {  470000000, 166667, 0xc2, 0x42 },
 179                {  526000000, 166667, 0xc2, 0x84 },
 180                {  999999999, 166667, 0xc2, 0xa4 },
 181        },
 182};
 183
 184/* Philips TDA6650/TDA6651
 185 * used in Panasonic ENV77H11D5
 186 */
 187static void tda665x_bw(struct dvb_frontend *fe, u8 *buf,
 188                       const struct dvb_frontend_parameters *params)
 189{
 190        if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
 191                buf[3] |= 0x08;
 192}
 193
 194static struct dvb_pll_desc dvb_pll_tda665x = {
 195        .name  = "Philips TDA6650/TDA6651",
 196        .min   =  44250000,
 197        .max   = 858000000,
 198        .set   = tda665x_bw,
 199        .iffreq= 36166667,
 200        .initdata = (u8[]){ 4, 0x0b, 0xf5, 0x85, 0xab },
 201        .count = 12,
 202        .entries = {
 203                {   93834000, 166667, 0xca, 0x61 /* 011 0 0 0  01 */ },
 204                {  123834000, 166667, 0xca, 0xa1 /* 101 0 0 0  01 */ },
 205                {  161000000, 166667, 0xca, 0xa1 /* 101 0 0 0  01 */ },
 206                {  163834000, 166667, 0xca, 0xc2 /* 110 0 0 0  10 */ },
 207                {  253834000, 166667, 0xca, 0x62 /* 011 0 0 0  10 */ },
 208                {  383834000, 166667, 0xca, 0xa2 /* 101 0 0 0  10 */ },
 209                {  443834000, 166667, 0xca, 0xc2 /* 110 0 0 0  10 */ },
 210                {  444000000, 166667, 0xca, 0xc4 /* 110 0 0 1  00 */ },
 211                {  583834000, 166667, 0xca, 0x64 /* 011 0 0 1  00 */ },
 212                {  793834000, 166667, 0xca, 0xa4 /* 101 0 0 1  00 */ },
 213                {  444834000, 166667, 0xca, 0xc4 /* 110 0 0 1  00 */ },
 214                {  861000000, 166667, 0xca, 0xe4 /* 111 0 0 1  00 */ },
 215        }
 216};
 217
 218/* Infineon TUA6034
 219 * used in LG TDTP E102P
 220 */
 221static void tua6034_bw(struct dvb_frontend *fe, u8 *buf,
 222                       const struct dvb_frontend_parameters *params)
 223{
 224        if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth)
 225                buf[3] |= 0x08;
 226}
 227
 228static struct dvb_pll_desc dvb_pll_tua6034 = {
 229        .name  = "Infineon TUA6034",
 230        .min   =  44250000,
 231        .max   = 858000000,
 232        .iffreq= 36166667,
 233        .count = 3,
 234        .set   = tua6034_bw,
 235        .entries = {
 236                {  174500000, 62500, 0xce, 0x01 },
 237                {  230000000, 62500, 0xce, 0x02 },
 238                {  999999999, 62500, 0xce, 0x04 },
 239        },
 240};
 241
 242/* ALPS TDED4
 243 * used in Nebula-Cards and USB boxes
 244 */
 245static void tded4_bw(struct dvb_frontend *fe, u8 *buf,
 246                     const struct dvb_frontend_parameters *params)
 247{
 248        if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
 249                buf[3] |= 0x04;
 250}
 251
 252static struct dvb_pll_desc dvb_pll_tded4 = {
 253        .name = "ALPS TDED4",
 254        .min = 47000000,
 255        .max = 863000000,
 256        .iffreq= 36166667,
 257        .set   = tded4_bw,
 258        .count = 4,
 259        .entries = {
 260                { 153000000, 166667, 0x85, 0x01 },
 261                { 470000000, 166667, 0x85, 0x02 },
 262                { 823000000, 166667, 0x85, 0x08 },
 263                { 999999999, 166667, 0x85, 0x88 },
 264        }
 265};
 266
 267/* ALPS TDHU2
 268 * used in AverTVHD MCE A180
 269 */
 270static struct dvb_pll_desc dvb_pll_tdhu2 = {
 271        .name = "ALPS TDHU2",
 272        .min = 54000000,
 273        .max = 864000000,
 274        .iffreq= 44000000,
 275        .count = 4,
 276        .entries = {
 277                { 162000000, 62500, 0x85, 0x01 },
 278                { 426000000, 62500, 0x85, 0x02 },
 279                { 782000000, 62500, 0x85, 0x08 },
 280                { 999999999, 62500, 0x85, 0x88 },
 281        }
 282};
 283
 284/* Samsung TBMV30111IN / TBMV30712IN1
 285 * used in Air2PC ATSC - 2nd generation (nxt2002)
 286 */
 287static struct dvb_pll_desc dvb_pll_samsung_tbmv = {
 288        .name = "Samsung TBMV30111IN / TBMV30712IN1",
 289        .min = 54000000,
 290        .max = 860000000,
 291        .iffreq= 44000000,
 292        .count = 6,
 293        .entries = {
 294                { 172000000, 166667, 0xb4, 0x01 },
 295                { 214000000, 166667, 0xb4, 0x02 },
 296                { 467000000, 166667, 0xbc, 0x02 },
 297                { 721000000, 166667, 0xbc, 0x08 },
 298                { 841000000, 166667, 0xf4, 0x08 },
 299                { 999999999, 166667, 0xfc, 0x02 },
 300        }
 301};
 302
 303/*
 304 * Philips SD1878 Tuner.
 305 */
 306static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
 307        .name  = "Philips SD1878",
 308        .min   =  950000,
 309        .max   = 2150000,
 310        .iffreq= 249, /* zero-IF, offset 249 is to round up */
 311        .count = 4,
 312        .entries = {
 313                { 1250000, 500, 0xc4, 0x00},
 314                { 1550000, 500, 0xc4, 0x40},
 315                { 2050000, 500, 0xc4, 0x80},
 316                { 2150000, 500, 0xc4, 0xc0},
 317        },
 318};
 319
 320static void opera1_bw(struct dvb_frontend *fe, u8 *buf,
 321                      const struct dvb_frontend_parameters *params)
 322{
 323        if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
 324                buf[2] |= 0x08;
 325}
 326
 327static struct dvb_pll_desc dvb_pll_opera1 = {
 328        .name  = "Opera Tuner",
 329        .min   =  900000,
 330        .max   = 2250000,
 331        .iffreq= 0,
 332        .set   = opera1_bw,
 333        .count = 8,
 334        .entries = {
 335                { 1064000, 500, 0xe5, 0xc6 },
 336                { 1169000, 500, 0xe5, 0xe6 },
 337                { 1299000, 500, 0xe5, 0x24 },
 338                { 1444000, 500, 0xe5, 0x44 },
 339                { 1606000, 500, 0xe5, 0x64 },
 340                { 1777000, 500, 0xe5, 0x84 },
 341                { 1941000, 500, 0xe5, 0xa4 },
 342                { 2250000, 500, 0xe5, 0xc4 },
 343        }
 344};
 345
 346static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf,
 347                       const struct dvb_frontend_parameters *params)
 348{
 349        struct dvb_pll_priv *priv = fe->tuner_priv;
 350        struct i2c_msg msg = {
 351                .addr = priv->pll_i2c_address,
 352                .flags = 0,
 353                .buf = buf,
 354                .len = 4
 355        };
 356        int result;
 357
 358        if (fe->ops.i2c_gate_ctrl)
 359                fe->ops.i2c_gate_ctrl(fe, 1);
 360
 361        result = i2c_transfer(priv->i2c, &msg, 1);
 362        if (result != 1)
 363                printk(KERN_ERR "%s: i2c_transfer failed:%d",
 364                        __func__, result);
 365
 366        buf[2] = 0x9e;
 367        buf[3] = 0x90;
 368
 369        return;
 370}
 371
 372/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */
 373static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
 374        .name   = "Samsung DTOS403IH102A",
 375        .min    =  44250000,
 376        .max    = 858000000,
 377        .iffreq =  36125000,
 378        .count  = 8,
 379        .set    = samsung_dtos403ih102a_set,
 380        .entries = {
 381                { 135000000, 62500, 0xbe, 0x01 },
 382                { 177000000, 62500, 0xf6, 0x01 },
 383                { 370000000, 62500, 0xbe, 0x02 },
 384                { 450000000, 62500, 0xf6, 0x02 },
 385                { 466000000, 62500, 0xfe, 0x02 },
 386                { 538000000, 62500, 0xbe, 0x08 },
 387                { 826000000, 62500, 0xf6, 0x08 },
 388                { 999999999, 62500, 0xfe, 0x08 },
 389        }
 390};
 391
 392/* ----------------------------------------------------------- */
 393
 394static struct dvb_pll_desc *pll_list[] = {
 395        [DVB_PLL_UNDEFINED]              = NULL,
 396        [DVB_PLL_THOMSON_DTT7579]        = &dvb_pll_thomson_dtt7579,
 397        [DVB_PLL_THOMSON_DTT759X]        = &dvb_pll_thomson_dtt759x,
 398        [DVB_PLL_LG_Z201]                = &dvb_pll_lg_z201,
 399        [DVB_PLL_UNKNOWN_1]              = &dvb_pll_unknown_1,
 400        [DVB_PLL_TUA6010XS]              = &dvb_pll_tua6010xs,
 401        [DVB_PLL_ENV57H1XD5]             = &dvb_pll_env57h1xd5,
 402        [DVB_PLL_TUA6034]                = &dvb_pll_tua6034,
 403        [DVB_PLL_TDA665X]                = &dvb_pll_tda665x,
 404        [DVB_PLL_TDED4]                  = &dvb_pll_tded4,
 405        [DVB_PLL_TDHU2]                  = &dvb_pll_tdhu2,
 406        [DVB_PLL_SAMSUNG_TBMV]           = &dvb_pll_samsung_tbmv,
 407        [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
 408        [DVB_PLL_OPERA1]                 = &dvb_pll_opera1,
 409        [DVB_PLL_SAMSUNG_DTOS403IH102A]  = &dvb_pll_samsung_dtos403ih102a,
 410};
 411
 412/* ----------------------------------------------------------- */
 413/* code                                                        */
 414
 415static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf,
 416                             const struct dvb_frontend_parameters *params)
 417{
 418        struct dvb_pll_priv *priv = fe->tuner_priv;
 419        struct dvb_pll_desc *desc = priv->pll_desc;
 420        u32 div;
 421        int i;
 422
 423        if (params->frequency != 0 && (params->frequency < desc->min ||
 424                                       params->frequency > desc->max))
 425                return -EINVAL;
 426
 427        for (i = 0; i < desc->count; i++) {
 428                if (params->frequency > desc->entries[i].limit)
 429                        continue;
 430                break;
 431        }
 432
 433        if (debug)
 434                printk("pll: %s: freq=%d | i=%d/%d\n", desc->name,
 435                       params->frequency, i, desc->count);
 436        if (i == desc->count)
 437                return -EINVAL;
 438
 439        div = (params->frequency + desc->iffreq +
 440               desc->entries[i].stepsize/2) / desc->entries[i].stepsize;
 441        buf[0] = div >> 8;
 442        buf[1] = div & 0xff;
 443        buf[2] = desc->entries[i].config;
 444        buf[3] = desc->entries[i].cb;
 445
 446        if (desc->set)
 447                desc->set(fe, buf, params);
 448
 449        if (debug)
 450                printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
 451                       desc->name, div, buf[0], buf[1], buf[2], buf[3]);
 452
 453        // calculate the frequency we set it to
 454        return (div * desc->entries[i].stepsize) - desc->iffreq;
 455}
 456
 457static int dvb_pll_release(struct dvb_frontend *fe)
 458{
 459        kfree(fe->tuner_priv);
 460        fe->tuner_priv = NULL;
 461        return 0;
 462}
 463
 464static int dvb_pll_sleep(struct dvb_frontend *fe)
 465{
 466        struct dvb_pll_priv *priv = fe->tuner_priv;
 467
 468        if (priv->i2c == NULL)
 469                return -EINVAL;
 470
 471        if (priv->pll_desc->sleepdata) {
 472                struct i2c_msg msg = { .flags = 0,
 473                        .addr = priv->pll_i2c_address,
 474                        .buf = priv->pll_desc->sleepdata + 1,
 475                        .len = priv->pll_desc->sleepdata[0] };
 476
 477                int result;
 478
 479                if (fe->ops.i2c_gate_ctrl)
 480                        fe->ops.i2c_gate_ctrl(fe, 1);
 481                if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
 482                        return result;
 483                }
 484                return 0;
 485        }
 486        /* Shouldn't be called when initdata is NULL, maybe BUG()? */
 487        return -EINVAL;
 488}
 489
 490static int dvb_pll_set_params(struct dvb_frontend *fe,
 491                              struct dvb_frontend_parameters *params)
 492{
 493        struct dvb_pll_priv *priv = fe->tuner_priv;
 494        u8 buf[4];
 495        struct i2c_msg msg =
 496                { .addr = priv->pll_i2c_address, .flags = 0,
 497                  .buf = buf, .len = sizeof(buf) };
 498        int result;
 499        u32 frequency = 0;
 500
 501        if (priv->i2c == NULL)
 502                return -EINVAL;
 503
 504        if ((result = dvb_pll_configure(fe, buf, params)) < 0)
 505                return result;
 506        else
 507                frequency = result;
 508
 509        if (fe->ops.i2c_gate_ctrl)
 510                fe->ops.i2c_gate_ctrl(fe, 1);
 511        if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
 512                return result;
 513        }
 514
 515        priv->frequency = frequency;
 516        priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
 517
 518        return 0;
 519}
 520
 521static int dvb_pll_calc_regs(struct dvb_frontend *fe,
 522                             struct dvb_frontend_parameters *params,
 523                             u8 *buf, int buf_len)
 524{
 525        struct dvb_pll_priv *priv = fe->tuner_priv;
 526        int result;
 527        u32 frequency = 0;
 528
 529        if (buf_len < 5)
 530                return -EINVAL;
 531
 532        if ((result = dvb_pll_configure(fe, buf+1, params)) < 0)
 533                return result;
 534        else
 535                frequency = result;
 536
 537        buf[0] = priv->pll_i2c_address;
 538
 539        priv->frequency = frequency;
 540        priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
 541
 542        return 5;
 543}
 544
 545static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 546{
 547        struct dvb_pll_priv *priv = fe->tuner_priv;
 548        *frequency = priv->frequency;
 549        return 0;
 550}
 551
 552static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
 553{
 554        struct dvb_pll_priv *priv = fe->tuner_priv;
 555        *bandwidth = priv->bandwidth;
 556        return 0;
 557}
 558
 559static int dvb_pll_init(struct dvb_frontend *fe)
 560{
 561        struct dvb_pll_priv *priv = fe->tuner_priv;
 562
 563        if (priv->i2c == NULL)
 564                return -EINVAL;
 565
 566        if (priv->pll_desc->initdata) {
 567                struct i2c_msg msg = { .flags = 0,
 568                        .addr = priv->pll_i2c_address,
 569                        .buf = priv->pll_desc->initdata + 1,
 570                        .len = priv->pll_desc->initdata[0] };
 571
 572                int result;
 573                if (fe->ops.i2c_gate_ctrl)
 574                        fe->ops.i2c_gate_ctrl(fe, 1);
 575                if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
 576                        return result;
 577                }
 578                return 0;
 579        }
 580        /* Shouldn't be called when initdata is NULL, maybe BUG()? */
 581        return -EINVAL;
 582}
 583
 584static struct dvb_tuner_ops dvb_pll_tuner_ops = {
 585        .release = dvb_pll_release,
 586        .sleep = dvb_pll_sleep,
 587        .init = dvb_pll_init,
 588        .set_params = dvb_pll_set_params,
 589        .calc_regs = dvb_pll_calc_regs,
 590        .get_frequency = dvb_pll_get_frequency,
 591        .get_bandwidth = dvb_pll_get_bandwidth,
 592};
 593
 594struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
 595                                    struct i2c_adapter *i2c,
 596                                    unsigned int pll_desc_id)
 597{
 598        u8 b1 [] = { 0 };
 599        struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD,
 600                               .buf = b1, .len = 1 };
 601        struct dvb_pll_priv *priv = NULL;
 602        int ret;
 603        struct dvb_pll_desc *desc;
 604
 605        if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
 606            (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))
 607                pll_desc_id = id[dvb_pll_devcount];
 608
 609        BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list));
 610
 611        desc = pll_list[pll_desc_id];
 612
 613        if (i2c != NULL) {
 614                if (fe->ops.i2c_gate_ctrl)
 615                        fe->ops.i2c_gate_ctrl(fe, 1);
 616
 617                ret = i2c_transfer (i2c, &msg, 1);
 618                if (ret != 1)
 619                        return NULL;
 620                if (fe->ops.i2c_gate_ctrl)
 621                             fe->ops.i2c_gate_ctrl(fe, 0);
 622        }
 623
 624        priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
 625        if (priv == NULL)
 626                return NULL;
 627
 628        priv->pll_i2c_address = pll_addr;
 629        priv->i2c = i2c;
 630        priv->pll_desc = desc;
 631        priv->nr = dvb_pll_devcount++;
 632
 633        memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops,
 634               sizeof(struct dvb_tuner_ops));
 635
 636        strncpy(fe->ops.tuner_ops.info.name, desc->name,
 637                sizeof(fe->ops.tuner_ops.info.name));
 638        fe->ops.tuner_ops.info.frequency_min = desc->min;
 639        fe->ops.tuner_ops.info.frequency_max = desc->max;
 640        if (!desc->initdata)
 641                fe->ops.tuner_ops.init = NULL;
 642        if (!desc->sleepdata)
 643                fe->ops.tuner_ops.sleep = NULL;
 644
 645        fe->tuner_priv = priv;
 646
 647        if ((debug) || (id[priv->nr] == pll_desc_id)) {
 648                printk("dvb-pll[%d]", priv->nr);
 649                if (i2c != NULL)
 650                        printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr);
 651                printk(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name,
 652                       id[priv->nr] == pll_desc_id ?
 653                                "insmod option" : "autodetected");
 654        }
 655
 656        return fe;
 657}
 658EXPORT_SYMBOL(dvb_pll_attach);
 659
 660MODULE_DESCRIPTION("dvb pll library");
 661MODULE_AUTHOR("Gerd Knorr");
 662MODULE_LICENSE("GPL");
 663
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.