OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [media/] [video/] [tda9887.c] - Blame information for rev 78

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
#include <linux/module.h>
2
#include <linux/kernel.h>
3
#include <linux/i2c.h>
4
#include <linux/types.h>
5
#include <linux/init.h>
6
#include <linux/errno.h>
7
#include <linux/slab.h>
8
#include <linux/delay.h>
9
#include <linux/videodev.h>
10
#include <media/v4l2-common.h>
11
#include <media/tuner.h>
12
#include "tuner-driver.h"
13
 
14
 
15
/* Chips:
16
   TDA9885 (PAL, NTSC)
17
   TDA9886 (PAL, SECAM, NTSC)
18
   TDA9887 (PAL, SECAM, NTSC, FM Radio)
19
 
20
   Used as part of several tuners
21
*/
22
 
23
#define tda9887_info(fmt, arg...) do {\
24
        printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \
25
                        i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
26
#define tda9887_dbg(fmt, arg...) do {\
27
        if (tuner_debug) \
28
                printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \
29
                        i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0)
30
 
31
struct tda9887_priv {
32
        struct tuner_i2c_props i2c_props;
33
 
34
        unsigned char      data[4];
35
};
36
 
37
/* ---------------------------------------------------------------------- */
38
 
39
#define UNSET       (-1U)
40
 
41
struct tvnorm {
42
        v4l2_std_id       std;
43
        char              *name;
44
        unsigned char     b;
45
        unsigned char     c;
46
        unsigned char     e;
47
};
48
 
49
/* ---------------------------------------------------------------------- */
50
 
51
//
52
// TDA defines
53
//
54
 
55
//// first reg (b)
56
#define cVideoTrapBypassOFF     0x00    // bit b0
57
#define cVideoTrapBypassON      0x01    // bit b0
58
 
59
#define cAutoMuteFmInactive     0x00    // bit b1
60
#define cAutoMuteFmActive       0x02    // bit b1
61
 
62
#define cIntercarrier           0x00    // bit b2
63
#define cQSS                    0x04    // bit b2
64
 
65
#define cPositiveAmTV           0x00    // bit b3:4
66
#define cFmRadio                0x08    // bit b3:4
67
#define cNegativeFmTV           0x10    // bit b3:4
68
 
69
 
70
#define cForcedMuteAudioON      0x20    // bit b5
71
#define cForcedMuteAudioOFF     0x00    // bit b5
72
 
73
#define cOutputPort1Active      0x00    // bit b6
74
#define cOutputPort1Inactive    0x40    // bit b6
75
 
76
#define cOutputPort2Active      0x00    // bit b7
77
#define cOutputPort2Inactive    0x80    // bit b7
78
 
79
 
80
//// second reg (c)
81
#define cDeemphasisOFF          0x00    // bit c5
82
#define cDeemphasisON           0x20    // bit c5
83
 
84
#define cDeemphasis75           0x00    // bit c6
85
#define cDeemphasis50           0x40    // bit c6
86
 
87
#define cAudioGain0             0x00    // bit c7
88
#define cAudioGain6             0x80    // bit c7
89
 
90
#define cTopMask                0x1f    // bit c0:4
91
#define cTopDefault             0x10    // bit c0:4
92
 
93
//// third reg (e)
94
#define cAudioIF_4_5             0x00    // bit e0:1
95
#define cAudioIF_5_5             0x01    // bit e0:1
96
#define cAudioIF_6_0             0x02    // bit e0:1
97
#define cAudioIF_6_5             0x03    // bit e0:1
98
 
99
 
100
#define cVideoIFMask            0x1c    // bit e2:4
101
/* Video IF selection in TV Mode (bit B3=0) */
102
#define cVideoIF_58_75           0x00    // bit e2:4
103
#define cVideoIF_45_75           0x04    // bit e2:4
104
#define cVideoIF_38_90           0x08    // bit e2:4
105
#define cVideoIF_38_00           0x0C    // bit e2:4
106
#define cVideoIF_33_90           0x10    // bit e2:4
107
#define cVideoIF_33_40           0x14    // bit e2:4
108
#define cRadioIF_45_75           0x18    // bit e2:4
109
#define cRadioIF_38_90           0x1C    // bit e2:4
110
 
111
/* IF1 selection in Radio Mode (bit B3=1) */
112
#define cRadioIF_33_30          0x00    // bit e2,4 (also 0x10,0x14)
113
#define cRadioIF_41_30          0x04    // bit e2,4
114
 
115
/* Output of AFC pin in radio mode when bit E7=1 */
116
#define cRadioAGC_SIF           0x00    // bit e3
117
#define cRadioAGC_FM            0x08    // bit e3
118
 
119
#define cTunerGainNormal         0x00    // bit e5
120
#define cTunerGainLow            0x20    // bit e5
121
 
122
#define cGating_18               0x00    // bit e6
123
#define cGating_36               0x40    // bit e6
124
 
125
#define cAgcOutON                0x80    // bit e7
126
#define cAgcOutOFF               0x00    // bit e7
127
 
128
/* ---------------------------------------------------------------------- */
129
 
130
static struct tvnorm tvnorms[] = {
131
        {
132
                .std   = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
133
                .name  = "PAL-BGHN",
134
                .b     = ( cNegativeFmTV  |
135
                           cQSS           ),
136
                .c     = ( cDeemphasisON  |
137
                           cDeemphasis50  |
138
                           cTopDefault),
139
                .e     = ( cGating_36     |
140
                           cAudioIF_5_5   |
141
                           cVideoIF_38_90 ),
142
        },{
143
                .std   = V4L2_STD_PAL_I,
144
                .name  = "PAL-I",
145
                .b     = ( cNegativeFmTV  |
146
                           cQSS           ),
147
                .c     = ( cDeemphasisON  |
148
                           cDeemphasis50  |
149
                           cTopDefault),
150
                .e     = ( cGating_36     |
151
                           cAudioIF_6_0   |
152
                           cVideoIF_38_90 ),
153
        },{
154
                .std   = V4L2_STD_PAL_DK,
155
                .name  = "PAL-DK",
156
                .b     = ( cNegativeFmTV  |
157
                           cQSS           ),
158
                .c     = ( cDeemphasisON  |
159
                           cDeemphasis50  |
160
                           cTopDefault),
161
                .e     = ( cGating_36     |
162
                           cAudioIF_6_5   |
163
                           cVideoIF_38_90 ),
164
        },{
165
                .std   = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
166
                .name  = "PAL-M/Nc",
167
                .b     = ( cNegativeFmTV  |
168
                           cQSS           ),
169
                .c     = ( cDeemphasisON  |
170
                           cDeemphasis75  |
171
                           cTopDefault),
172
                .e     = ( cGating_36     |
173
                           cAudioIF_4_5   |
174
                           cVideoIF_45_75 ),
175
        },{
176
                .std   = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
177
                .name  = "SECAM-BGH",
178
                .b     = ( cPositiveAmTV  |
179
                           cQSS           ),
180
                .c     = ( cTopDefault),
181
                .e     = ( cGating_36     |
182
                           cAudioIF_5_5   |
183
                           cVideoIF_38_90 ),
184
        },{
185
                .std   = V4L2_STD_SECAM_L,
186
                .name  = "SECAM-L",
187
                .b     = ( cPositiveAmTV  |
188
                           cQSS           ),
189
                .c     = ( cTopDefault),
190
                .e     = ( cGating_36     |
191
                           cAudioIF_6_5   |
192
                           cVideoIF_38_90 ),
193
        },{
194
                .std   = V4L2_STD_SECAM_LC,
195
                .name  = "SECAM-L'",
196
                .b     = ( cOutputPort2Inactive |
197
                           cPositiveAmTV  |
198
                           cQSS           ),
199
                .c     = ( cTopDefault),
200
                .e     = ( cGating_36     |
201
                           cAudioIF_6_5   |
202
                           cVideoIF_33_90 ),
203
        },{
204
                .std   = V4L2_STD_SECAM_DK,
205
                .name  = "SECAM-DK",
206
                .b     = ( cNegativeFmTV  |
207
                           cQSS           ),
208
                .c     = ( cDeemphasisON  |
209
                           cDeemphasis50  |
210
                           cTopDefault),
211
                .e     = ( cGating_36     |
212
                           cAudioIF_6_5   |
213
                           cVideoIF_38_90 ),
214
        },{
215
                .std   = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
216
                .name  = "NTSC-M",
217
                .b     = ( cNegativeFmTV  |
218
                           cQSS           ),
219
                .c     = ( cDeemphasisON  |
220
                           cDeemphasis75  |
221
                           cTopDefault),
222
                .e     = ( cGating_36     |
223
                           cAudioIF_4_5   |
224
                           cVideoIF_45_75 ),
225
        },{
226
                .std   = V4L2_STD_NTSC_M_JP,
227
                .name  = "NTSC-M-JP",
228
                .b     = ( cNegativeFmTV  |
229
                           cQSS           ),
230
                .c     = ( cDeemphasisON  |
231
                           cDeemphasis50  |
232
                           cTopDefault),
233
                .e     = ( cGating_36     |
234
                           cAudioIF_4_5   |
235
                           cVideoIF_58_75 ),
236
        }
237
};
238
 
239
static struct tvnorm radio_stereo = {
240
        .name = "Radio Stereo",
241
        .b    = ( cFmRadio       |
242
                  cQSS           ),
243
        .c    = ( cDeemphasisOFF |
244
                  cAudioGain6    |
245
                  cTopDefault),
246
        .e    = ( cTunerGainLow  |
247
                  cAudioIF_5_5   |
248
                  cRadioIF_38_90 ),
249
};
250
 
251
static struct tvnorm radio_mono = {
252
        .name = "Radio Mono",
253
        .b    = ( cFmRadio       |
254
                  cQSS           ),
255
        .c    = ( cDeemphasisON  |
256
                  cDeemphasis75  |
257
                  cTopDefault),
258
        .e    = ( cTunerGainLow  |
259
                  cAudioIF_5_5   |
260
                  cRadioIF_38_90 ),
261
};
262
 
263
/* ---------------------------------------------------------------------- */
264
 
265
static void dump_read_message(struct tuner *t, unsigned char *buf)
266
{
267
        static char *afc[16] = {
268
                "- 12.5 kHz",
269
                "- 37.5 kHz",
270
                "- 62.5 kHz",
271
                "- 87.5 kHz",
272
                "-112.5 kHz",
273
                "-137.5 kHz",
274
                "-162.5 kHz",
275
                "-187.5 kHz [min]",
276
                "+187.5 kHz [max]",
277
                "+162.5 kHz",
278
                "+137.5 kHz",
279
                "+112.5 kHz",
280
                "+ 87.5 kHz",
281
                "+ 62.5 kHz",
282
                "+ 37.5 kHz",
283
                "+ 12.5 kHz",
284
        };
285
        tda9887_info("read: 0x%2x\n", buf[0]);
286
        tda9887_info("  after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
287
        tda9887_info("  afc            : %s\n", afc[(buf[0] >> 1) & 0x0f]);
288
        tda9887_info("  fmif level     : %s\n", (buf[0] & 0x20) ? "high" : "low");
289
        tda9887_info("  afc window     : %s\n", (buf[0] & 0x40) ? "in" : "out");
290
        tda9887_info("  vfi level      : %s\n", (buf[0] & 0x80) ? "high" : "low");
291
}
292
 
293
static void dump_write_message(struct tuner *t, unsigned char *buf)
294
{
295
        static char *sound[4] = {
296
                "AM/TV",
297
                "FM/radio",
298
                "FM/TV",
299
                "FM/radio"
300
        };
301
        static char *adjust[32] = {
302
                "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
303
                "-8",  "-7",  "-6",  "-5",  "-4",  "-3",  "-2",  "-1",
304
                "0",   "+1",  "+2",  "+3",  "+4",  "+5",  "+6",  "+7",
305
                "+8",  "+9",  "+10", "+11", "+12", "+13", "+14", "+15"
306
        };
307
        static char *deemph[4] = {
308
                "no", "no", "75", "50"
309
        };
310
        static char *carrier[4] = {
311
                "4.5 MHz",
312
                "5.5 MHz",
313
                "6.0 MHz",
314
                "6.5 MHz / AM"
315
        };
316
        static char *vif[8] = {
317
                "58.75 MHz",
318
                "45.75 MHz",
319
                "38.9 MHz",
320
                "38.0 MHz",
321
                "33.9 MHz",
322
                "33.4 MHz",
323
                "45.75 MHz + pin13",
324
                "38.9 MHz + pin13",
325
        };
326
        static char *rif[4] = {
327
                "44 MHz",
328
                "52 MHz",
329
                "52 MHz",
330
                "44 MHz",
331
        };
332
 
333
        tda9887_info("write: byte B 0x%02x\n",buf[1]);
334
        tda9887_info("  B0   video mode      : %s\n",
335
               (buf[1] & 0x01) ? "video trap" : "sound trap");
336
        tda9887_info("  B1   auto mute fm    : %s\n",
337
               (buf[1] & 0x02) ? "yes" : "no");
338
        tda9887_info("  B2   carrier mode    : %s\n",
339
               (buf[1] & 0x04) ? "QSS" : "Intercarrier");
340
        tda9887_info("  B3-4 tv sound/radio  : %s\n",
341
               sound[(buf[1] & 0x18) >> 3]);
342
        tda9887_info("  B5   force mute audio: %s\n",
343
               (buf[1] & 0x20) ? "yes" : "no");
344
        tda9887_info("  B6   output port 1   : %s\n",
345
               (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
346
        tda9887_info("  B7   output port 2   : %s\n",
347
               (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
348
 
349
        tda9887_info("write: byte C 0x%02x\n",buf[2]);
350
        tda9887_info("  C0-4 top adjustment  : %s dB\n", adjust[buf[2] & 0x1f]);
351
        tda9887_info("  C5-6 de-emphasis     : %s\n", deemph[(buf[2] & 0x60) >> 5]);
352
        tda9887_info("  C7   audio gain      : %s\n",
353
               (buf[2] & 0x80) ? "-6" : "0");
354
 
355
        tda9887_info("write: byte E 0x%02x\n",buf[3]);
356
        tda9887_info("  E0-1 sound carrier   : %s\n",
357
               carrier[(buf[3] & 0x03)]);
358
        tda9887_info("  E6   l pll gating   : %s\n",
359
               (buf[3] & 0x40) ? "36" : "13");
360
 
361
        if (buf[1] & 0x08) {
362
                /* radio */
363
                tda9887_info("  E2-4 video if        : %s\n",
364
                       rif[(buf[3] & 0x0c) >> 2]);
365
                tda9887_info("  E7   vif agc output  : %s\n",
366
                       (buf[3] & 0x80)
367
                       ? ((buf[3] & 0x10) ? "fm-agc radio" : "sif-agc radio")
368
                       : "fm radio carrier afc");
369
        } else {
370
                /* video */
371
                tda9887_info("  E2-4 video if        : %s\n",
372
                       vif[(buf[3] & 0x1c) >> 2]);
373
                tda9887_info("  E5   tuner gain      : %s\n",
374
                       (buf[3] & 0x80)
375
                       ? ((buf[3] & 0x20) ? "external" : "normal")
376
                       : ((buf[3] & 0x20) ? "minimum"  : "normal"));
377
                tda9887_info("  E7   vif agc output  : %s\n",
378
                       (buf[3] & 0x80)
379
                       ? ((buf[3] & 0x20)
380
                          ? "pin3 port, pin22 vif agc out"
381
                          : "pin22 port, pin3 vif acg ext in")
382
                       : "pin3+pin22 port");
383
        }
384
        tda9887_info("--\n");
385
}
386
 
387
/* ---------------------------------------------------------------------- */
388
 
389
static int tda9887_set_tvnorm(struct tuner *t, char *buf)
390
{
391
        struct tvnorm *norm = NULL;
392
        int i;
393
 
394
        if (t->mode == V4L2_TUNER_RADIO) {
395
                if (t->audmode == V4L2_TUNER_MODE_MONO)
396
                        norm = &radio_mono;
397
                else
398
                        norm = &radio_stereo;
399
        } else {
400
                for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
401
                        if (tvnorms[i].std & t->std) {
402
                                norm = tvnorms+i;
403
                                break;
404
                        }
405
                }
406
        }
407
        if (NULL == norm) {
408
                tda9887_dbg("Unsupported tvnorm entry - audio muted\n");
409
                return -1;
410
        }
411
 
412
        tda9887_dbg("configure for: %s\n",norm->name);
413
        buf[1] = norm->b;
414
        buf[2] = norm->c;
415
        buf[3] = norm->e;
416
        return 0;
417
}
418
 
419
static unsigned int port1  = UNSET;
420
static unsigned int port2  = UNSET;
421
static unsigned int qss    = UNSET;
422
static unsigned int adjust = UNSET;
423
 
424
module_param(port1, int, 0644);
425
module_param(port2, int, 0644);
426
module_param(qss, int, 0644);
427
module_param(adjust, int, 0644);
428
 
429
static int tda9887_set_insmod(struct tuner *t, char *buf)
430
{
431
        if (UNSET != port1) {
432
                if (port1)
433
                        buf[1] |= cOutputPort1Inactive;
434
                else
435
                        buf[1] &= ~cOutputPort1Inactive;
436
        }
437
        if (UNSET != port2) {
438
                if (port2)
439
                        buf[1] |= cOutputPort2Inactive;
440
                else
441
                        buf[1] &= ~cOutputPort2Inactive;
442
        }
443
 
444
        if (UNSET != qss) {
445
                if (qss)
446
                        buf[1] |= cQSS;
447
                else
448
                        buf[1] &= ~cQSS;
449
        }
450
 
451
        if (adjust >= 0x00 && adjust < 0x20) {
452
                buf[2] &= ~cTopMask;
453
                buf[2] |= adjust;
454
        }
455
        return 0;
456
}
457
 
458
static int tda9887_set_config(struct tuner *t, char *buf)
459
{
460
        if (t->tda9887_config & TDA9887_PORT1_ACTIVE)
461
                buf[1] &= ~cOutputPort1Inactive;
462
        if (t->tda9887_config & TDA9887_PORT1_INACTIVE)
463
                buf[1] |= cOutputPort1Inactive;
464
        if (t->tda9887_config & TDA9887_PORT2_ACTIVE)
465
                buf[1] &= ~cOutputPort2Inactive;
466
        if (t->tda9887_config & TDA9887_PORT2_INACTIVE)
467
                buf[1] |= cOutputPort2Inactive;
468
 
469
        if (t->tda9887_config & TDA9887_QSS)
470
                buf[1] |= cQSS;
471
        if (t->tda9887_config & TDA9887_INTERCARRIER)
472
                buf[1] &= ~cQSS;
473
 
474
        if (t->tda9887_config & TDA9887_AUTOMUTE)
475
                buf[1] |= cAutoMuteFmActive;
476
        if (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) {
477
                buf[2] &= ~0x60;
478
                switch (t->tda9887_config & TDA9887_DEEMPHASIS_MASK) {
479
                case TDA9887_DEEMPHASIS_NONE:
480
                        buf[2] |= cDeemphasisOFF;
481
                        break;
482
                case TDA9887_DEEMPHASIS_50:
483
                        buf[2] |= cDeemphasisON | cDeemphasis50;
484
                        break;
485
                case TDA9887_DEEMPHASIS_75:
486
                        buf[2] |= cDeemphasisON | cDeemphasis75;
487
                        break;
488
                }
489
        }
490
        if (t->tda9887_config & TDA9887_TOP_SET) {
491
                buf[2] &= ~cTopMask;
492
                buf[2] |= (t->tda9887_config >> 8) & cTopMask;
493
        }
494
        if ((t->tda9887_config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC))
495
                buf[1] &= ~cQSS;
496
        if (t->tda9887_config & TDA9887_GATING_18)
497
                buf[3] &= ~cGating_36;
498
 
499
        if (t->mode == V4L2_TUNER_RADIO) {
500
                if (t->tda9887_config & TDA9887_RIF_41_3) {
501
                        buf[3] &= ~cVideoIFMask;
502
                        buf[3] |= cRadioIF_41_30;
503
                }
504
                if (t->tda9887_config & TDA9887_GAIN_NORMAL)
505
                        buf[3] &= ~cTunerGainLow;
506
        }
507
 
508
        return 0;
509
}
510
 
511
/* ---------------------------------------------------------------------- */
512
 
513
static int tda9887_status(struct tuner *t)
514
{
515
        struct tda9887_priv *priv = t->priv;
516
        unsigned char buf[1];
517
        int rc;
518
 
519
        memset(buf,0,sizeof(buf));
520
        if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,buf,1)))
521
                tda9887_info("i2c i/o error: rc == %d (should be 1)\n",rc);
522
        dump_read_message(t, buf);
523
        return 0;
524
}
525
 
526
static void tda9887_configure(struct tuner *t)
527
{
528
        struct tda9887_priv *priv = t->priv;
529
        int rc;
530
 
531
        memset(priv->data,0,sizeof(priv->data));
532
        tda9887_set_tvnorm(t,priv->data);
533
 
534
        /* A note on the port settings:
535
           These settings tend to depend on the specifics of the board.
536
           By default they are set to inactive (bit value 1) by this driver,
537
           overwriting any changes made by the tvnorm. This means that it
538
           is the responsibility of the module using the tda9887 to set
539
           these values in case of changes in the tvnorm.
540
           In many cases port 2 should be made active (0) when selecting
541
           SECAM-L, and port 2 should remain inactive (1) for SECAM-L'.
542
 
543
           For the other standards the tda9887 application note says that
544
           the ports should be set to active (0), but, again, that may
545
           differ depending on the precise hardware configuration.
546
         */
547
        priv->data[1] |= cOutputPort1Inactive;
548
        priv->data[1] |= cOutputPort2Inactive;
549
 
550
        tda9887_set_config(t,priv->data);
551
        tda9887_set_insmod(t,priv->data);
552
 
553
        if (t->mode == T_STANDBY) {
554
                priv->data[1] |= cForcedMuteAudioON;
555
        }
556
 
557
        tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
558
                priv->data[1],priv->data[2],priv->data[3]);
559
        if (tuner_debug > 1)
560
                dump_write_message(t, priv->data);
561
 
562
        if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,priv->data,4)))
563
                tda9887_info("i2c i/o error: rc == %d (should be 4)\n",rc);
564
 
565
        if (tuner_debug > 2) {
566
                msleep_interruptible(1000);
567
                tda9887_status(t);
568
        }
569
}
570
 
571
/* ---------------------------------------------------------------------- */
572
 
573
static void tda9887_tuner_status(struct tuner *t)
574
{
575
        struct tda9887_priv *priv = t->priv;
576
        tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", priv->data[1], priv->data[2], priv->data[3]);
577
}
578
 
579
static int tda9887_get_afc(struct tuner *t)
580
{
581
        struct tda9887_priv *priv = t->priv;
582
        static int AFC_BITS_2_kHz[] = {
583
                -12500,  -37500,  -62500,  -97500,
584
                -112500, -137500, -162500, -187500,
585
                187500,  162500,  137500,  112500,
586
                97500 ,  62500,   37500 ,  12500
587
        };
588
        int afc=0;
589
        __u8 reg = 0;
590
 
591
        if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,&reg,1))
592
                afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
593
 
594
        return afc;
595
}
596
 
597
static void tda9887_standby(struct tuner *t)
598
{
599
        tda9887_configure(t);
600
}
601
 
602
static void tda9887_set_freq(struct tuner *t, unsigned int freq)
603
{
604
        tda9887_configure(t);
605
}
606
 
607
static void tda9887_release(struct tuner *t)
608
{
609
        kfree(t->priv);
610
        t->priv = NULL;
611
}
612
 
613
static struct tuner_operations tda9887_tuner_ops = {
614
        .set_tv_freq    = tda9887_set_freq,
615
        .set_radio_freq = tda9887_set_freq,
616
        .standby        = tda9887_standby,
617
        .tuner_status   = tda9887_tuner_status,
618
        .get_afc        = tda9887_get_afc,
619
        .release        = tda9887_release,
620
};
621
 
622
int tda9887_tuner_init(struct tuner *t)
623
{
624
        struct tda9887_priv *priv = NULL;
625
 
626
        priv = kzalloc(sizeof(struct tda9887_priv), GFP_KERNEL);
627
        if (priv == NULL)
628
                return -ENOMEM;
629
        t->priv = priv;
630
 
631
        priv->i2c_props.addr = t->i2c.addr;
632
        priv->i2c_props.adap = t->i2c.adapter;
633
 
634
        strlcpy(t->i2c.name, "tda9887", sizeof(t->i2c.name));
635
 
636
        tda9887_info("tda988[5/6/7] found @ 0x%x (%s)\n", t->i2c.addr,
637
                                                t->i2c.driver->driver.name);
638
 
639
        memcpy(&t->ops, &tda9887_tuner_ops, sizeof(struct tuner_operations));
640
 
641
        return 0;
642
}
643
 
644
/*
645
 * Overrides for Emacs so that we follow Linus's tabbing style.
646
 * ---------------------------------------------------------------------------
647
 * Local variables:
648
 * c-basic-offset: 8
649
 * End:
650
 */

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.