Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/common/tuners/mxl5007t.c
15112 views
1
/*
2
* mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
3
*
4
* Copyright (C) 2008, 2009 Michael Krufky <[email protected]>
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/i2c.h>
22
#include <linux/types.h>
23
#include <linux/videodev2.h>
24
#include "tuner-i2c.h"
25
#include "mxl5007t.h"
26
27
static DEFINE_MUTEX(mxl5007t_list_mutex);
28
static LIST_HEAD(hybrid_tuner_instance_list);
29
30
static int mxl5007t_debug;
31
module_param_named(debug, mxl5007t_debug, int, 0644);
32
MODULE_PARM_DESC(debug, "set debug level");
33
34
/* ------------------------------------------------------------------------- */
35
36
#define mxl_printk(kern, fmt, arg...) \
37
printk(kern "%s: " fmt "\n", __func__, ##arg)
38
39
#define mxl_err(fmt, arg...) \
40
mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg)
41
42
#define mxl_warn(fmt, arg...) \
43
mxl_printk(KERN_WARNING, fmt, ##arg)
44
45
#define mxl_info(fmt, arg...) \
46
mxl_printk(KERN_INFO, fmt, ##arg)
47
48
#define mxl_debug(fmt, arg...) \
49
({ \
50
if (mxl5007t_debug) \
51
mxl_printk(KERN_DEBUG, fmt, ##arg); \
52
})
53
54
#define mxl_fail(ret) \
55
({ \
56
int __ret; \
57
__ret = (ret < 0); \
58
if (__ret) \
59
mxl_printk(KERN_ERR, "error %d on line %d", \
60
ret, __LINE__); \
61
__ret; \
62
})
63
64
/* ------------------------------------------------------------------------- */
65
66
#define MHz 1000000
67
68
enum mxl5007t_mode {
69
MxL_MODE_ISDBT = 0,
70
MxL_MODE_DVBT = 1,
71
MxL_MODE_ATSC = 2,
72
MxL_MODE_CABLE = 0x10,
73
};
74
75
enum mxl5007t_chip_version {
76
MxL_UNKNOWN_ID = 0x00,
77
MxL_5007_V1_F1 = 0x11,
78
MxL_5007_V1_F2 = 0x12,
79
MxL_5007_V4 = 0x14,
80
MxL_5007_V2_100_F1 = 0x21,
81
MxL_5007_V2_100_F2 = 0x22,
82
MxL_5007_V2_200_F1 = 0x23,
83
MxL_5007_V2_200_F2 = 0x24,
84
};
85
86
struct reg_pair_t {
87
u8 reg;
88
u8 val;
89
};
90
91
/* ------------------------------------------------------------------------- */
92
93
static struct reg_pair_t init_tab[] = {
94
{ 0x02, 0x06 },
95
{ 0x03, 0x48 },
96
{ 0x05, 0x04 },
97
{ 0x06, 0x10 },
98
{ 0x2e, 0x15 }, /* OVERRIDE */
99
{ 0x30, 0x10 }, /* OVERRIDE */
100
{ 0x45, 0x58 }, /* OVERRIDE */
101
{ 0x48, 0x19 }, /* OVERRIDE */
102
{ 0x52, 0x03 }, /* OVERRIDE */
103
{ 0x53, 0x44 }, /* OVERRIDE */
104
{ 0x6a, 0x4b }, /* OVERRIDE */
105
{ 0x76, 0x00 }, /* OVERRIDE */
106
{ 0x78, 0x18 }, /* OVERRIDE */
107
{ 0x7a, 0x17 }, /* OVERRIDE */
108
{ 0x85, 0x06 }, /* OVERRIDE */
109
{ 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
110
{ 0, 0 }
111
};
112
113
static struct reg_pair_t init_tab_cable[] = {
114
{ 0x02, 0x06 },
115
{ 0x03, 0x48 },
116
{ 0x05, 0x04 },
117
{ 0x06, 0x10 },
118
{ 0x09, 0x3f },
119
{ 0x0a, 0x3f },
120
{ 0x0b, 0x3f },
121
{ 0x2e, 0x15 }, /* OVERRIDE */
122
{ 0x30, 0x10 }, /* OVERRIDE */
123
{ 0x45, 0x58 }, /* OVERRIDE */
124
{ 0x48, 0x19 }, /* OVERRIDE */
125
{ 0x52, 0x03 }, /* OVERRIDE */
126
{ 0x53, 0x44 }, /* OVERRIDE */
127
{ 0x6a, 0x4b }, /* OVERRIDE */
128
{ 0x76, 0x00 }, /* OVERRIDE */
129
{ 0x78, 0x18 }, /* OVERRIDE */
130
{ 0x7a, 0x17 }, /* OVERRIDE */
131
{ 0x85, 0x06 }, /* OVERRIDE */
132
{ 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
133
{ 0, 0 }
134
};
135
136
/* ------------------------------------------------------------------------- */
137
138
static struct reg_pair_t reg_pair_rftune[] = {
139
{ 0x0f, 0x00 }, /* abort tune */
140
{ 0x0c, 0x15 },
141
{ 0x0d, 0x40 },
142
{ 0x0e, 0x0e },
143
{ 0x1f, 0x87 }, /* OVERRIDE */
144
{ 0x20, 0x1f }, /* OVERRIDE */
145
{ 0x21, 0x87 }, /* OVERRIDE */
146
{ 0x22, 0x1f }, /* OVERRIDE */
147
{ 0x80, 0x01 }, /* freq dependent */
148
{ 0x0f, 0x01 }, /* start tune */
149
{ 0, 0 }
150
};
151
152
/* ------------------------------------------------------------------------- */
153
154
struct mxl5007t_state {
155
struct list_head hybrid_tuner_instance_list;
156
struct tuner_i2c_props i2c_props;
157
158
struct mutex lock;
159
160
struct mxl5007t_config *config;
161
162
enum mxl5007t_chip_version chip_id;
163
164
struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)];
165
struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)];
166
struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)];
167
168
u32 frequency;
169
u32 bandwidth;
170
};
171
172
/* ------------------------------------------------------------------------- */
173
174
/* called by _init and _rftun to manipulate the register arrays */
175
176
static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val)
177
{
178
unsigned int i = 0;
179
180
while (reg_pair[i].reg || reg_pair[i].val) {
181
if (reg_pair[i].reg == reg) {
182
reg_pair[i].val &= ~mask;
183
reg_pair[i].val |= val;
184
}
185
i++;
186
187
}
188
return;
189
}
190
191
static void copy_reg_bits(struct reg_pair_t *reg_pair1,
192
struct reg_pair_t *reg_pair2)
193
{
194
unsigned int i, j;
195
196
i = j = 0;
197
198
while (reg_pair1[i].reg || reg_pair1[i].val) {
199
while (reg_pair2[j].reg || reg_pair2[j].val) {
200
if (reg_pair1[i].reg != reg_pair2[j].reg) {
201
j++;
202
continue;
203
}
204
reg_pair2[j].val = reg_pair1[i].val;
205
break;
206
}
207
i++;
208
}
209
return;
210
}
211
212
/* ------------------------------------------------------------------------- */
213
214
static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
215
enum mxl5007t_mode mode,
216
s32 if_diff_out_level)
217
{
218
switch (mode) {
219
case MxL_MODE_ATSC:
220
set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12);
221
break;
222
case MxL_MODE_DVBT:
223
set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11);
224
break;
225
case MxL_MODE_ISDBT:
226
set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10);
227
break;
228
case MxL_MODE_CABLE:
229
set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1);
230
set_reg_bits(state->tab_init_cable, 0x0a, 0xff,
231
8 - if_diff_out_level);
232
set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17);
233
break;
234
default:
235
mxl_fail(-EINVAL);
236
}
237
return;
238
}
239
240
static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
241
enum mxl5007t_if_freq if_freq,
242
int invert_if)
243
{
244
u8 val;
245
246
switch (if_freq) {
247
case MxL_IF_4_MHZ:
248
val = 0x00;
249
break;
250
case MxL_IF_4_5_MHZ:
251
val = 0x02;
252
break;
253
case MxL_IF_4_57_MHZ:
254
val = 0x03;
255
break;
256
case MxL_IF_5_MHZ:
257
val = 0x04;
258
break;
259
case MxL_IF_5_38_MHZ:
260
val = 0x05;
261
break;
262
case MxL_IF_6_MHZ:
263
val = 0x06;
264
break;
265
case MxL_IF_6_28_MHZ:
266
val = 0x07;
267
break;
268
case MxL_IF_9_1915_MHZ:
269
val = 0x08;
270
break;
271
case MxL_IF_35_25_MHZ:
272
val = 0x09;
273
break;
274
case MxL_IF_36_15_MHZ:
275
val = 0x0a;
276
break;
277
case MxL_IF_44_MHZ:
278
val = 0x0b;
279
break;
280
default:
281
mxl_fail(-EINVAL);
282
return;
283
}
284
set_reg_bits(state->tab_init, 0x02, 0x0f, val);
285
286
/* set inverted IF or normal IF */
287
set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
288
289
return;
290
}
291
292
static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
293
enum mxl5007t_xtal_freq xtal_freq)
294
{
295
switch (xtal_freq) {
296
case MxL_XTAL_16_MHZ:
297
/* select xtal freq & ref freq */
298
set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00);
299
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00);
300
break;
301
case MxL_XTAL_20_MHZ:
302
set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10);
303
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01);
304
break;
305
case MxL_XTAL_20_25_MHZ:
306
set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20);
307
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02);
308
break;
309
case MxL_XTAL_20_48_MHZ:
310
set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30);
311
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03);
312
break;
313
case MxL_XTAL_24_MHZ:
314
set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40);
315
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04);
316
break;
317
case MxL_XTAL_25_MHZ:
318
set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50);
319
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05);
320
break;
321
case MxL_XTAL_25_14_MHZ:
322
set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60);
323
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06);
324
break;
325
case MxL_XTAL_27_MHZ:
326
set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70);
327
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07);
328
break;
329
case MxL_XTAL_28_8_MHZ:
330
set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80);
331
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08);
332
break;
333
case MxL_XTAL_32_MHZ:
334
set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90);
335
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09);
336
break;
337
case MxL_XTAL_40_MHZ:
338
set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0);
339
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a);
340
break;
341
case MxL_XTAL_44_MHZ:
342
set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0);
343
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b);
344
break;
345
case MxL_XTAL_48_MHZ:
346
set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0);
347
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c);
348
break;
349
case MxL_XTAL_49_3811_MHZ:
350
set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0);
351
set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d);
352
break;
353
default:
354
mxl_fail(-EINVAL);
355
return;
356
}
357
358
return;
359
}
360
361
static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
362
enum mxl5007t_mode mode)
363
{
364
struct mxl5007t_config *cfg = state->config;
365
366
memcpy(&state->tab_init, &init_tab, sizeof(init_tab));
367
memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable));
368
369
mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level);
370
mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
371
mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
372
373
set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable);
374
set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3);
375
set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp);
376
377
if (mode >= MxL_MODE_CABLE) {
378
copy_reg_bits(state->tab_init, state->tab_init_cable);
379
return state->tab_init_cable;
380
} else
381
return state->tab_init;
382
}
383
384
/* ------------------------------------------------------------------------- */
385
386
enum mxl5007t_bw_mhz {
387
MxL_BW_6MHz = 6,
388
MxL_BW_7MHz = 7,
389
MxL_BW_8MHz = 8,
390
};
391
392
static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
393
enum mxl5007t_bw_mhz bw)
394
{
395
u8 val;
396
397
switch (bw) {
398
case MxL_BW_6MHz:
399
val = 0x15; /* set DIG_MODEINDEX, DIG_MODEINDEX_A,
400
* and DIG_MODEINDEX_CSF */
401
break;
402
case MxL_BW_7MHz:
403
val = 0x2a;
404
break;
405
case MxL_BW_8MHz:
406
val = 0x3f;
407
break;
408
default:
409
mxl_fail(-EINVAL);
410
return;
411
}
412
set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val);
413
414
return;
415
}
416
417
static struct
418
reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
419
u32 rf_freq, enum mxl5007t_bw_mhz bw)
420
{
421
u32 dig_rf_freq = 0;
422
u32 temp;
423
u32 frac_divider = 1000000;
424
unsigned int i;
425
426
memcpy(&state->tab_rftune, &reg_pair_rftune, sizeof(reg_pair_rftune));
427
428
mxl5007t_set_bw_bits(state, bw);
429
430
/* Convert RF frequency into 16 bits =>
431
* 10 bit integer (MHz) + 6 bit fraction */
432
dig_rf_freq = rf_freq / MHz;
433
434
temp = rf_freq % MHz;
435
436
for (i = 0; i < 6; i++) {
437
dig_rf_freq <<= 1;
438
frac_divider /= 2;
439
if (temp > frac_divider) {
440
temp -= frac_divider;
441
dig_rf_freq++;
442
}
443
}
444
445
/* add to have shift center point by 7.8124 kHz */
446
if (temp > 7812)
447
dig_rf_freq++;
448
449
set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq);
450
set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8));
451
452
if (rf_freq >= 333000000)
453
set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40);
454
455
return state->tab_rftune;
456
}
457
458
/* ------------------------------------------------------------------------- */
459
460
static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val)
461
{
462
u8 buf[] = { reg, val };
463
struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
464
.buf = buf, .len = 2 };
465
int ret;
466
467
ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
468
if (ret != 1) {
469
mxl_err("failed!");
470
return -EREMOTEIO;
471
}
472
return 0;
473
}
474
475
static int mxl5007t_write_regs(struct mxl5007t_state *state,
476
struct reg_pair_t *reg_pair)
477
{
478
unsigned int i = 0;
479
int ret = 0;
480
481
while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) {
482
ret = mxl5007t_write_reg(state,
483
reg_pair[i].reg, reg_pair[i].val);
484
i++;
485
}
486
return ret;
487
}
488
489
static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
490
{
491
struct i2c_msg msg[] = {
492
{ .addr = state->i2c_props.addr, .flags = 0,
493
.buf = &reg, .len = 1 },
494
{ .addr = state->i2c_props.addr, .flags = I2C_M_RD,
495
.buf = val, .len = 1 },
496
};
497
int ret;
498
499
ret = i2c_transfer(state->i2c_props.adap, msg, 2);
500
if (ret != 2) {
501
mxl_err("failed!");
502
return -EREMOTEIO;
503
}
504
return 0;
505
}
506
507
static int mxl5007t_soft_reset(struct mxl5007t_state *state)
508
{
509
u8 d = 0xff;
510
struct i2c_msg msg = {
511
.addr = state->i2c_props.addr, .flags = 0,
512
.buf = &d, .len = 1
513
};
514
int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
515
516
if (ret != 1) {
517
mxl_err("failed!");
518
return -EREMOTEIO;
519
}
520
return 0;
521
}
522
523
static int mxl5007t_tuner_init(struct mxl5007t_state *state,
524
enum mxl5007t_mode mode)
525
{
526
struct reg_pair_t *init_regs;
527
int ret;
528
529
ret = mxl5007t_soft_reset(state);
530
if (mxl_fail(ret))
531
goto fail;
532
533
/* calculate initialization reg array */
534
init_regs = mxl5007t_calc_init_regs(state, mode);
535
536
ret = mxl5007t_write_regs(state, init_regs);
537
if (mxl_fail(ret))
538
goto fail;
539
mdelay(1);
540
fail:
541
return ret;
542
}
543
544
static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz,
545
enum mxl5007t_bw_mhz bw)
546
{
547
struct reg_pair_t *rf_tune_regs;
548
int ret;
549
550
/* calculate channel change reg array */
551
rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw);
552
553
ret = mxl5007t_write_regs(state, rf_tune_regs);
554
if (mxl_fail(ret))
555
goto fail;
556
msleep(3);
557
fail:
558
return ret;
559
}
560
561
/* ------------------------------------------------------------------------- */
562
563
static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
564
int *rf_locked, int *ref_locked)
565
{
566
u8 d;
567
int ret;
568
569
*rf_locked = 0;
570
*ref_locked = 0;
571
572
ret = mxl5007t_read_reg(state, 0xd8, &d);
573
if (mxl_fail(ret))
574
goto fail;
575
576
if ((d & 0x0c) == 0x0c)
577
*rf_locked = 1;
578
579
if ((d & 0x03) == 0x03)
580
*ref_locked = 1;
581
fail:
582
return ret;
583
}
584
585
/* ------------------------------------------------------------------------- */
586
587
static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
588
{
589
struct mxl5007t_state *state = fe->tuner_priv;
590
int rf_locked, ref_locked, ret;
591
592
*status = 0;
593
594
if (fe->ops.i2c_gate_ctrl)
595
fe->ops.i2c_gate_ctrl(fe, 1);
596
597
ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked);
598
if (mxl_fail(ret))
599
goto fail;
600
mxl_debug("%s%s", rf_locked ? "rf locked " : "",
601
ref_locked ? "ref locked" : "");
602
603
if ((rf_locked) || (ref_locked))
604
*status |= TUNER_STATUS_LOCKED;
605
fail:
606
if (fe->ops.i2c_gate_ctrl)
607
fe->ops.i2c_gate_ctrl(fe, 0);
608
609
return ret;
610
}
611
612
/* ------------------------------------------------------------------------- */
613
614
static int mxl5007t_set_params(struct dvb_frontend *fe,
615
struct dvb_frontend_parameters *params)
616
{
617
struct mxl5007t_state *state = fe->tuner_priv;
618
enum mxl5007t_bw_mhz bw;
619
enum mxl5007t_mode mode;
620
int ret;
621
u32 freq = params->frequency;
622
623
if (fe->ops.info.type == FE_ATSC) {
624
switch (params->u.vsb.modulation) {
625
case VSB_8:
626
case VSB_16:
627
mode = MxL_MODE_ATSC;
628
break;
629
case QAM_64:
630
case QAM_256:
631
mode = MxL_MODE_CABLE;
632
break;
633
default:
634
mxl_err("modulation not set!");
635
return -EINVAL;
636
}
637
bw = MxL_BW_6MHz;
638
} else if (fe->ops.info.type == FE_OFDM) {
639
switch (params->u.ofdm.bandwidth) {
640
case BANDWIDTH_6_MHZ:
641
bw = MxL_BW_6MHz;
642
break;
643
case BANDWIDTH_7_MHZ:
644
bw = MxL_BW_7MHz;
645
break;
646
case BANDWIDTH_8_MHZ:
647
bw = MxL_BW_8MHz;
648
break;
649
default:
650
mxl_err("bandwidth not set!");
651
return -EINVAL;
652
}
653
mode = MxL_MODE_DVBT;
654
} else {
655
mxl_err("modulation type not supported!");
656
return -EINVAL;
657
}
658
659
if (fe->ops.i2c_gate_ctrl)
660
fe->ops.i2c_gate_ctrl(fe, 1);
661
662
mutex_lock(&state->lock);
663
664
ret = mxl5007t_tuner_init(state, mode);
665
if (mxl_fail(ret))
666
goto fail;
667
668
ret = mxl5007t_tuner_rf_tune(state, freq, bw);
669
if (mxl_fail(ret))
670
goto fail;
671
672
state->frequency = freq;
673
state->bandwidth = (fe->ops.info.type == FE_OFDM) ?
674
params->u.ofdm.bandwidth : 0;
675
fail:
676
mutex_unlock(&state->lock);
677
678
if (fe->ops.i2c_gate_ctrl)
679
fe->ops.i2c_gate_ctrl(fe, 0);
680
681
return ret;
682
}
683
684
/* ------------------------------------------------------------------------- */
685
686
static int mxl5007t_init(struct dvb_frontend *fe)
687
{
688
struct mxl5007t_state *state = fe->tuner_priv;
689
int ret;
690
691
if (fe->ops.i2c_gate_ctrl)
692
fe->ops.i2c_gate_ctrl(fe, 1);
693
694
/* wake from standby */
695
ret = mxl5007t_write_reg(state, 0x01, 0x01);
696
mxl_fail(ret);
697
698
if (fe->ops.i2c_gate_ctrl)
699
fe->ops.i2c_gate_ctrl(fe, 0);
700
701
return ret;
702
}
703
704
static int mxl5007t_sleep(struct dvb_frontend *fe)
705
{
706
struct mxl5007t_state *state = fe->tuner_priv;
707
int ret;
708
709
if (fe->ops.i2c_gate_ctrl)
710
fe->ops.i2c_gate_ctrl(fe, 1);
711
712
/* enter standby mode */
713
ret = mxl5007t_write_reg(state, 0x01, 0x00);
714
mxl_fail(ret);
715
ret = mxl5007t_write_reg(state, 0x0f, 0x00);
716
mxl_fail(ret);
717
718
if (fe->ops.i2c_gate_ctrl)
719
fe->ops.i2c_gate_ctrl(fe, 0);
720
721
return ret;
722
}
723
724
/* ------------------------------------------------------------------------- */
725
726
static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
727
{
728
struct mxl5007t_state *state = fe->tuner_priv;
729
*frequency = state->frequency;
730
return 0;
731
}
732
733
static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
734
{
735
struct mxl5007t_state *state = fe->tuner_priv;
736
*bandwidth = state->bandwidth;
737
return 0;
738
}
739
740
static int mxl5007t_release(struct dvb_frontend *fe)
741
{
742
struct mxl5007t_state *state = fe->tuner_priv;
743
744
mutex_lock(&mxl5007t_list_mutex);
745
746
if (state)
747
hybrid_tuner_release_state(state);
748
749
mutex_unlock(&mxl5007t_list_mutex);
750
751
fe->tuner_priv = NULL;
752
753
return 0;
754
}
755
756
/* ------------------------------------------------------------------------- */
757
758
static struct dvb_tuner_ops mxl5007t_tuner_ops = {
759
.info = {
760
.name = "MaxLinear MxL5007T",
761
},
762
.init = mxl5007t_init,
763
.sleep = mxl5007t_sleep,
764
.set_params = mxl5007t_set_params,
765
.get_status = mxl5007t_get_status,
766
.get_frequency = mxl5007t_get_frequency,
767
.get_bandwidth = mxl5007t_get_bandwidth,
768
.release = mxl5007t_release,
769
};
770
771
static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
772
{
773
char *name;
774
int ret;
775
u8 id;
776
777
ret = mxl5007t_read_reg(state, 0xd9, &id);
778
if (mxl_fail(ret))
779
goto fail;
780
781
switch (id) {
782
case MxL_5007_V1_F1:
783
name = "MxL5007.v1.f1";
784
break;
785
case MxL_5007_V1_F2:
786
name = "MxL5007.v1.f2";
787
break;
788
case MxL_5007_V2_100_F1:
789
name = "MxL5007.v2.100.f1";
790
break;
791
case MxL_5007_V2_100_F2:
792
name = "MxL5007.v2.100.f2";
793
break;
794
case MxL_5007_V2_200_F1:
795
name = "MxL5007.v2.200.f1";
796
break;
797
case MxL_5007_V2_200_F2:
798
name = "MxL5007.v2.200.f2";
799
break;
800
case MxL_5007_V4:
801
name = "MxL5007T.v4";
802
break;
803
default:
804
name = "MxL5007T";
805
printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id);
806
id = MxL_UNKNOWN_ID;
807
}
808
state->chip_id = id;
809
mxl_info("%s detected @ %d-%04x", name,
810
i2c_adapter_id(state->i2c_props.adap),
811
state->i2c_props.addr);
812
return 0;
813
fail:
814
mxl_warn("unable to identify device @ %d-%04x",
815
i2c_adapter_id(state->i2c_props.adap),
816
state->i2c_props.addr);
817
818
state->chip_id = MxL_UNKNOWN_ID;
819
return ret;
820
}
821
822
struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
823
struct i2c_adapter *i2c, u8 addr,
824
struct mxl5007t_config *cfg)
825
{
826
struct mxl5007t_state *state = NULL;
827
int instance, ret;
828
829
mutex_lock(&mxl5007t_list_mutex);
830
instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
831
hybrid_tuner_instance_list,
832
i2c, addr, "mxl5007t");
833
switch (instance) {
834
case 0:
835
goto fail;
836
case 1:
837
/* new tuner instance */
838
state->config = cfg;
839
840
mutex_init(&state->lock);
841
842
if (fe->ops.i2c_gate_ctrl)
843
fe->ops.i2c_gate_ctrl(fe, 1);
844
845
ret = mxl5007t_get_chip_id(state);
846
847
if (fe->ops.i2c_gate_ctrl)
848
fe->ops.i2c_gate_ctrl(fe, 0);
849
850
/* check return value of mxl5007t_get_chip_id */
851
if (mxl_fail(ret))
852
goto fail;
853
break;
854
default:
855
/* existing tuner instance */
856
break;
857
}
858
fe->tuner_priv = state;
859
mutex_unlock(&mxl5007t_list_mutex);
860
861
memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops,
862
sizeof(struct dvb_tuner_ops));
863
864
return fe;
865
fail:
866
mutex_unlock(&mxl5007t_list_mutex);
867
868
mxl5007t_release(fe);
869
return NULL;
870
}
871
EXPORT_SYMBOL_GPL(mxl5007t_attach);
872
MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
873
MODULE_AUTHOR("Michael Krufky <[email protected]>");
874
MODULE_LICENSE("GPL");
875
MODULE_VERSION("0.2");
876
877
/*
878
* Overrides for Emacs so that we follow Linus's tabbing style.
879
* ---------------------------------------------------------------------------
880
* Local variables:
881
* c-basic-offset: 8
882
* End:
883
*/
884
885