aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-21 00:14:42 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-21 00:14:42 -0400
commitf894d18380e7e7ff05f6622ccb75d2881922c6e9 (patch)
treee3c11b831b68096239a49dec539a49e49c1d90b7 /drivers/media/dvb/frontends
parentd13ff0559fea73f237a01669887d2c10e11d7662 (diff)
parentd20b27478d6ccf7c4c8de4f09db2bdbaec82a6c0 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (277 commits) V4L/DVB (8415): gspca: Infinite loop in i2c_w() of etoms. V4L/DVB (8414): videodev/cx18: fix get_index bug and error-handling lock-ups V4L/DVB (8411): videobuf-dma-contig.c: fix 64-bit build for pre-2.6.24 kernels V4L/DVB (8410): sh_mobile_ceu_camera: fix 64-bit compiler warnings V4L/DVB (8397): video: convert select VIDEO_ZORAN_ZR36060 into depends on V4L/DVB (8396): video: Fix Kbuild dependency for VIDEO_IR_I2C V4L/DVB (8395): saa7134: Fix Kbuild dependency of ir-kbd-i2c V4L/DVB (8394): ir-common: CodingStyle fix: move EXPORT_SYMBOL_GPL to their proper places V4L/DVB (8393): media/video: Fix depencencies for VIDEOBUF V4L/DVB (8392): media/Kconfig: Convert V4L1_COMPAT select into "depends on" V4L/DVB (8390): videodev: add comment and remove magic number. V4L/DVB (8389): videodev: simplify get_index() V4L/DVB (8387): Some cosmetic changes V4L/DVB (8381): ov7670: fix compile warnings V4L/DVB (8380): saa7115: use saa7115_auto instead of saa711x as the autodetect driver name. V4L/DVB (8379): saa7127: Make device detection optional V4L/DVB (8378): cx18: move cx18_av_vbi_setup to av-core.c and rename to cx18_av_std_setup V4L/DVB (8377): ivtv/cx18: ensure the default control values are correct V4L/DVB (8376): cx25840: move cx25840_vbi_setup to core.c and rename to cx25840_std_setup V4L/DVB (8374): gspca: No conflict of 0c45:6011 with the sn9c102 driver. ...
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r--drivers/media/dvb/frontends/au8522.c1
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c47
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h1
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c24
-rw-r--r--drivers/media/dvb/frontends/s5h1409.c1
-rw-r--r--drivers/media/dvb/frontends/s5h1411.c1
-rw-r--r--drivers/media/dvb/frontends/tda10023.c197
-rw-r--r--drivers/media/dvb/frontends/tda1002x.h41
8 files changed, 217 insertions, 96 deletions
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c
index 03900d241a76..f7b71657f0f6 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522.c
@@ -26,7 +26,6 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include "dvb_frontend.h" 28#include "dvb_frontend.h"
29#include "dvb-pll.h"
30#include "au8522.h" 29#include "au8522.h"
31 30
32struct au8522_state { 31struct au8522_state {
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index a054894ff481..ea058153ebfa 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -343,6 +343,52 @@ static struct dvb_pll_desc dvb_pll_opera1 = {
343 } 343 }
344}; 344};
345 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
346/* ----------------------------------------------------------- */ 392/* ----------------------------------------------------------- */
347 393
348static struct dvb_pll_desc *pll_list[] = { 394static struct dvb_pll_desc *pll_list[] = {
@@ -360,6 +406,7 @@ static struct dvb_pll_desc *pll_list[] = {
360 [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv, 406 [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv,
361 [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261, 407 [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
362 [DVB_PLL_OPERA1] = &dvb_pll_opera1, 408 [DVB_PLL_OPERA1] = &dvb_pll_opera1,
409 [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a,
363}; 410};
364 411
365/* ----------------------------------------------------------- */ 412/* ----------------------------------------------------------- */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 872ca29e7cf3..05239f579ccf 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -22,6 +22,7 @@
22#define DVB_PLL_SAMSUNG_TBMV 11 22#define DVB_PLL_SAMSUNG_TBMV 11
23#define DVB_PLL_PHILIPS_SD1878_TDA8261 12 23#define DVB_PLL_PHILIPS_SD1878_TDA8261 12
24#define DVB_PLL_OPERA1 13 24#define DVB_PLL_OPERA1 13
25#define DVB_PLL_SAMSUNG_DTOS403IH102A 14
25 26
26/** 27/**
27 * Attach a dvb-pll to the supplied frontend structure. 28 * Attach a dvb-pll to the supplied frontend structure.
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index f0195c8272f4..056387b41a8f 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -226,11 +226,16 @@ static int lgdt330x_init(struct dvb_frontend* fe)
226 0x4c, 0x14 226 0x4c, 0x14
227 }; 227 };
228 228
229 static u8 flip_lgdt3303_init_data[] = { 229 static u8 flip_1_lgdt3303_init_data[] = {
230 0x4c, 0x14, 230 0x4c, 0x14,
231 0x87, 0xf3 231 0x87, 0xf3
232 }; 232 };
233 233
234 static u8 flip_2_lgdt3303_init_data[] = {
235 0x4c, 0x14,
236 0x87, 0xda
237 };
238
234 struct lgdt330x_state* state = fe->demodulator_priv; 239 struct lgdt330x_state* state = fe->demodulator_priv;
235 char *chip_name; 240 char *chip_name;
236 int err; 241 int err;
@@ -243,10 +248,19 @@ static int lgdt330x_init(struct dvb_frontend* fe)
243 break; 248 break;
244 case LGDT3303: 249 case LGDT3303:
245 chip_name = "LGDT3303"; 250 chip_name = "LGDT3303";
246 if (state->config->clock_polarity_flip) { 251 switch (state->config->clock_polarity_flip) {
247 err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data, 252 case 2:
248 sizeof(flip_lgdt3303_init_data)); 253 err = i2c_write_demod_bytes(state,
249 } else { 254 flip_2_lgdt3303_init_data,
255 sizeof(flip_2_lgdt3303_init_data));
256 break;
257 case 1:
258 err = i2c_write_demod_bytes(state,
259 flip_1_lgdt3303_init_data,
260 sizeof(flip_1_lgdt3303_init_data));
261 break;
262 case 0:
263 default:
250 err = i2c_write_demod_bytes(state, lgdt3303_init_data, 264 err = i2c_write_demod_bytes(state, lgdt3303_init_data,
251 sizeof(lgdt3303_init_data)); 265 sizeof(lgdt3303_init_data));
252 } 266 }
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index b999ec424ff7..5ddb2dca305c 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -26,7 +26,6 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include "dvb_frontend.h" 28#include "dvb_frontend.h"
29#include "dvb-pll.h"
30#include "s5h1409.h" 29#include "s5h1409.h"
31 30
32struct s5h1409_state { 31struct s5h1409_state {
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
index eb5bfc99d4e9..cff360ce1ba3 100644
--- a/drivers/media/dvb/frontends/s5h1411.c
+++ b/drivers/media/dvb/frontends/s5h1411.c
@@ -26,7 +26,6 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include "dvb_frontend.h" 28#include "dvb_frontend.h"
29#include "dvb-pll.h"
30#include "s5h1411.h" 29#include "s5h1411.h"
31 30
32struct s5h1411_state { 31struct s5h1411_state {
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c
index c6ff5b82ff80..a3c34eecdee9 100644
--- a/drivers/media/dvb/frontends/tda10023.c
+++ b/drivers/media/dvb/frontends/tda10023.c
@@ -38,75 +38,29 @@
38#include "dvb_frontend.h" 38#include "dvb_frontend.h"
39#include "tda1002x.h" 39#include "tda1002x.h"
40 40
41#define REG0_INIT_VAL 0x23
41 42
42struct tda10023_state { 43struct tda10023_state {
43 struct i2c_adapter* i2c; 44 struct i2c_adapter* i2c;
44 /* configuration settings */ 45 /* configuration settings */
45 const struct tda1002x_config* config; 46 const struct tda10023_config *config;
46 struct dvb_frontend frontend; 47 struct dvb_frontend frontend;
47 48
48 u8 pwm; 49 u8 pwm;
49 u8 reg0; 50 u8 reg0;
50};
51 51
52 /* clock settings */
53 u32 xtal;
54 u8 pll_m;
55 u8 pll_p;
56 u8 pll_n;
57 u32 sysclk;
58};
52 59
53#define dprintk(x...) 60#define dprintk(x...)
54 61
55static int verbose; 62static int verbose;
56 63
57#define XTAL 28920000UL
58#define PLL_M 8UL
59#define PLL_P 4UL
60#define PLL_N 1UL
61#define SYSCLK (XTAL*PLL_M/(PLL_N*PLL_P)) // -> 57840000
62
63static u8 tda10023_inittab[]={
64 // reg mask val
65 0x2a,0xff,0x02, // PLL3, Bypass, Power Down
66 0xff,0x64,0x00, // Sleep 100ms
67 0x2a,0xff,0x03, // PLL3, Bypass, Power Down
68 0xff,0x64,0x00, // Sleep 100ms
69 0x28,0xff,PLL_M-1, // PLL1 M=8
70 0x29,0xff,((PLL_P-1)<<6)|(PLL_N-1), // PLL2
71 0x00,0xff,0x23, // GPR FSAMPLING=1
72 0x2a,0xff,0x08, // PLL3 PSACLK=1
73 0xff,0x64,0x00, // Sleep 100ms
74 0x1f,0xff,0x00, // RESET
75 0xff,0x64,0x00, // Sleep 100ms
76 0xe6,0x0c,0x04, // RSCFG_IND
77 0x10,0xc0,0x80, // DECDVBCFG1 PBER=1
78
79 0x0e,0xff,0x82, // GAIN1
80 0x03,0x08,0x08, // CLKCONF DYN=1
81 0x2e,0xbf,0x30, // AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 PPWMTUN=0 PPWMIF=0
82 0x01,0xff,0x30, // AGCREF
83 0x1e,0x84,0x84, // CONTROL SACLK_ON=1
84 0x1b,0xff,0xc8, // ADC TWOS=1
85 0x3b,0xff,0xff, // IFMAX
86 0x3c,0xff,0x00, // IFMIN
87 0x34,0xff,0x00, // PWMREF
88 0x35,0xff,0xff, // TUNMAX
89 0x36,0xff,0x00, // TUNMIN
90 0x06,0xff,0x7f, // EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 // 0x77
91 0x1c,0x30,0x30, // EQCONF2 STEPALGO=SGNALGO=1
92 0x37,0xff,0xf6, // DELTAF_LSB
93 0x38,0xff,0xff, // DELTAF_MSB
94 0x02,0xff,0x93, // AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3
95 0x2d,0xff,0xf6, // SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2
96 0x04,0x10,0x00, // SWRAMP=1
97 0x12,0xff,0xa1, // INTP1 POCLKP=1 FEL=1 MFS=0
98 0x2b,0x01,0xa1, // INTS1
99 0x20,0xff,0x04, // INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=?
100 0x2c,0xff,0x0d, // INTP/S TRIP=0 TRIS=0
101 0xc4,0xff,0x00,
102 0xc3,0x30,0x00,
103 0xb5,0xff,0x19, // ERAGC_THD
104 0x00,0x03,0x01, // GPR, CLBS soft reset
105 0x00,0x03,0x03, // GPR, CLBS soft reset
106 0xff,0x64,0x00, // Sleep 100ms
107 0xff,0xff,0xff
108};
109
110static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) 64static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
111{ 65{
112 u8 b0 [] = { reg }; 66 u8 b0 [] = { reg };
@@ -219,30 +173,34 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
219 s16 SFIL=0; 173 s16 SFIL=0;
220 u16 NDEC = 0; 174 u16 NDEC = 0;
221 175
222 if (sr < (u32)(SYSCLK/98.40)) { 176 /* avoid floating point operations multiplying syscloc and divider
177 by 10 */
178 u32 sysclk_x_10 = state->sysclk * 10;
179
180 if (sr < (u32)(sysclk_x_10/984)) {
223 NDEC=3; 181 NDEC=3;
224 SFIL=1; 182 SFIL=1;
225 } else if (sr<(u32)(SYSCLK/64.0)) { 183 } else if (sr < (u32)(sysclk_x_10/640)) {
226 NDEC=3; 184 NDEC=3;
227 SFIL=0; 185 SFIL=0;
228 } else if (sr<(u32)(SYSCLK/49.2)) { 186 } else if (sr < (u32)(sysclk_x_10/492)) {
229 NDEC=2; 187 NDEC=2;
230 SFIL=1; 188 SFIL=1;
231 } else if (sr<(u32)(SYSCLK/32.0)) { 189 } else if (sr < (u32)(sysclk_x_10/320)) {
232 NDEC=2; 190 NDEC=2;
233 SFIL=0; 191 SFIL=0;
234 } else if (sr<(u32)(SYSCLK/24.6)) { 192 } else if (sr < (u32)(sysclk_x_10/246)) {
235 NDEC=1; 193 NDEC=1;
236 SFIL=1; 194 SFIL=1;
237 } else if (sr<(u32)(SYSCLK/16.0)) { 195 } else if (sr < (u32)(sysclk_x_10/160)) {
238 NDEC=1; 196 NDEC=1;
239 SFIL=0; 197 SFIL=0;
240 } else if (sr<(u32)(SYSCLK/12.3)) { 198 } else if (sr < (u32)(sysclk_x_10/123)) {
241 NDEC=0; 199 NDEC=0;
242 SFIL=1; 200 SFIL=1;
243 } 201 }
244 202
245 BDRI=SYSCLK*16; 203 BDRI = (state->sysclk)*16;
246 BDRI>>=NDEC; 204 BDRI>>=NDEC;
247 BDRI +=sr/2; 205 BDRI +=sr/2;
248 BDRI /=sr; 206 BDRI /=sr;
@@ -255,11 +213,12 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
255 213
256 BDRX=1<<(24+NDEC); 214 BDRX=1<<(24+NDEC);
257 BDRX*=sr; 215 BDRX*=sr;
258 do_div(BDRX,SYSCLK); // BDRX/=SYSCLK; 216 do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */
259 217
260 BDR=(s32)BDRX; 218 BDR=(s32)BDRX;
261 } 219 }
262// printk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",sr,BDR,BDRI,NDEC); 220 dprintk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",
221 sr, BDR, BDRI, NDEC);
263 tda10023_writebit (state, 0x03, 0xc0, NDEC<<6); 222 tda10023_writebit (state, 0x03, 0xc0, NDEC<<6);
264 tda10023_writereg (state, 0x0a, BDR&255); 223 tda10023_writereg (state, 0x0a, BDR&255);
265 tda10023_writereg (state, 0x0b, (BDR>>8)&255); 224 tda10023_writereg (state, 0x0b, (BDR>>8)&255);
@@ -272,8 +231,67 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
272static int tda10023_init (struct dvb_frontend *fe) 231static int tda10023_init (struct dvb_frontend *fe)
273{ 232{
274 struct tda10023_state* state = fe->demodulator_priv; 233 struct tda10023_state* state = fe->demodulator_priv;
234 u8 tda10023_inittab[] = {
235/* reg mask val */
236/* 000 */ 0x2a, 0xff, 0x02, /* PLL3, Bypass, Power Down */
237/* 003 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
238/* 006 */ 0x2a, 0xff, 0x03, /* PLL3, Bypass, Power Down */
239/* 009 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
240 /* PLL1 */
241/* 012 */ 0x28, 0xff, (state->pll_m-1),
242 /* PLL2 */
243/* 015 */ 0x29, 0xff, ((state->pll_p-1)<<6)|(state->pll_n-1),
244 /* GPR FSAMPLING=1 */
245/* 018 */ 0x00, 0xff, REG0_INIT_VAL,
246/* 021 */ 0x2a, 0xff, 0x08, /* PLL3 PSACLK=1 */
247/* 024 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
248/* 027 */ 0x1f, 0xff, 0x00, /* RESET */
249/* 030 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
250/* 033 */ 0xe6, 0x0c, 0x04, /* RSCFG_IND */
251/* 036 */ 0x10, 0xc0, 0x80, /* DECDVBCFG1 PBER=1 */
252
253/* 039 */ 0x0e, 0xff, 0x82, /* GAIN1 */
254/* 042 */ 0x03, 0x08, 0x08, /* CLKCONF DYN=1 */
255/* 045 */ 0x2e, 0xbf, 0x30, /* AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1
256 PPWMTUN=0 PPWMIF=0 */
257/* 048 */ 0x01, 0xff, 0x30, /* AGCREF */
258/* 051 */ 0x1e, 0x84, 0x84, /* CONTROL SACLK_ON=1 */
259/* 054 */ 0x1b, 0xff, 0xc8, /* ADC TWOS=1 */
260/* 057 */ 0x3b, 0xff, 0xff, /* IFMAX */
261/* 060 */ 0x3c, 0xff, 0x00, /* IFMIN */
262/* 063 */ 0x34, 0xff, 0x00, /* PWMREF */
263/* 066 */ 0x35, 0xff, 0xff, /* TUNMAX */
264/* 069 */ 0x36, 0xff, 0x00, /* TUNMIN */
265/* 072 */ 0x06, 0xff, 0x7f, /* EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 */
266/* 075 */ 0x1c, 0x30, 0x30, /* EQCONF2 STEPALGO=SGNALGO=1 */
267/* 078 */ 0x37, 0xff, 0xf6, /* DELTAF_LSB */
268/* 081 */ 0x38, 0xff, 0xff, /* DELTAF_MSB */
269/* 084 */ 0x02, 0xff, 0x93, /* AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 */
270/* 087 */ 0x2d, 0xff, 0xf6, /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */
271/* 090 */ 0x04, 0x10, 0x00, /* SWRAMP=1 */
272/* 093 */ 0x12, 0xff, TDA10023_OUTPUT_MODE_PARALLEL_B, /*
273 INTP1 POCLKP=1 FEL=1 MFS=0 */
274/* 096 */ 0x2b, 0x01, 0xa1, /* INTS1 */
275/* 099 */ 0x20, 0xff, 0x04, /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */
276/* 102 */ 0x2c, 0xff, 0x0d, /* INTP/S TRIP=0 TRIS=0 */
277/* 105 */ 0xc4, 0xff, 0x00,
278/* 108 */ 0xc3, 0x30, 0x00,
279/* 111 */ 0xb5, 0xff, 0x19, /* ERAGC_THD */
280/* 114 */ 0x00, 0x03, 0x01, /* GPR, CLBS soft reset */
281/* 117 */ 0x00, 0x03, 0x03, /* GPR, CLBS soft reset */
282/* 120 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
283/* 123 */ 0xff, 0xff, 0xff
284};
285 dprintk("DVB: TDA10023(%d): init chip\n", fe->dvb->num);
286
287 /* override default values if set in config */
288 if (state->config->deltaf) {
289 tda10023_inittab[80] = (state->config->deltaf & 0xff);
290 tda10023_inittab[83] = (state->config->deltaf >> 8);
291 }
275 292
276 dprintk("DVB: TDA10023(%d): init chip\n", fe->adapter->num); 293 if (state->config->output_mode)
294 tda10023_inittab[95] = state->config->output_mode;
277 295
278 tda10023_writetab(state, tda10023_inittab); 296 tda10023_writetab(state, tda10023_inittab);
279 297
@@ -460,12 +478,11 @@ static void tda10023_release(struct dvb_frontend* fe)
460 478
461static struct dvb_frontend_ops tda10023_ops; 479static struct dvb_frontend_ops tda10023_ops;
462 480
463struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, 481struct dvb_frontend *tda10023_attach(const struct tda10023_config *config,
464 struct i2c_adapter* i2c, 482 struct i2c_adapter *i2c,
465 u8 pwm) 483 u8 pwm)
466{ 484{
467 struct tda10023_state* state = NULL; 485 struct tda10023_state* state = NULL;
468 int i;
469 486
470 /* allocate memory for the internal state */ 487 /* allocate memory for the internal state */
471 state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL); 488 state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL);
@@ -474,22 +491,40 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
474 /* setup the state */ 491 /* setup the state */
475 state->config = config; 492 state->config = config;
476 state->i2c = i2c; 493 state->i2c = i2c;
477 memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
478 state->pwm = pwm;
479 for (i=0; i < ARRAY_SIZE(tda10023_inittab);i+=3) {
480 if (tda10023_inittab[i] == 0x00) {
481 state->reg0 = tda10023_inittab[i+2];
482 break;
483 }
484 }
485 494
486 // Wakeup if in standby 495 /* wakeup if in standby */
487 tda10023_writereg (state, 0x00, 0x33); 496 tda10023_writereg (state, 0x00, 0x33);
488 /* check if the demod is there */ 497 /* check if the demod is there */
489 if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; 498 if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
490 499
491 /* create dvb_frontend */ 500 /* create dvb_frontend */
492 memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); 501 memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
502 state->pwm = pwm;
503 state->reg0 = REG0_INIT_VAL;
504 if (state->config->xtal) {
505 state->xtal = state->config->xtal;
506 state->pll_m = state->config->pll_m;
507 state->pll_p = state->config->pll_p;
508 state->pll_n = state->config->pll_n;
509 } else {
510 /* set default values if not defined in config */
511 state->xtal = 28920000;
512 state->pll_m = 8;
513 state->pll_p = 4;
514 state->pll_n = 1;
515 }
516
517 /* calc sysclk */
518 state->sysclk = (state->xtal * state->pll_m / \
519 (state->pll_n * state->pll_p));
520
521 state->frontend.ops.info.symbol_rate_min = (state->sysclk/2)/64;
522 state->frontend.ops.info.symbol_rate_max = (state->sysclk/2)/4;
523
524 dprintk("DVB: TDA10023 %s: xtal:%d pll_m:%d pll_p:%d pll_n:%d\n",
525 __func__, state->xtal, state->pll_m, state->pll_p,
526 state->pll_n);
527
493 state->frontend.demodulator_priv = state; 528 state->frontend.demodulator_priv = state;
494 return &state->frontend; 529 return &state->frontend;
495 530
@@ -504,10 +539,10 @@ static struct dvb_frontend_ops tda10023_ops = {
504 .name = "Philips TDA10023 DVB-C", 539 .name = "Philips TDA10023 DVB-C",
505 .type = FE_QAM, 540 .type = FE_QAM,
506 .frequency_stepsize = 62500, 541 .frequency_stepsize = 62500,
507 .frequency_min = 47000000, 542 .frequency_min = 47000000,
508 .frequency_max = 862000000, 543 .frequency_max = 862000000,
509 .symbol_rate_min = (SYSCLK/2)/64, /* SACLK/64 == (SYSCLK/2)/64 */ 544 .symbol_rate_min = 0, /* set in tda10023_attach */
510 .symbol_rate_max = (SYSCLK/2)/4, /* SACLK/4 */ 545 .symbol_rate_max = 0, /* set in tda10023_attach */
511 .caps = 0x400 | //FE_CAN_QAM_4 546 .caps = 0x400 | //FE_CAN_QAM_4
512 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | 547 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
513 FE_CAN_QAM_128 | FE_CAN_QAM_256 | 548 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h
index 1bcc0d44b90b..04d19418bf20 100644
--- a/drivers/media/dvb/frontends/tda1002x.h
+++ b/drivers/media/dvb/frontends/tda1002x.h
@@ -26,13 +26,37 @@
26 26
27#include <linux/dvb/frontend.h> 27#include <linux/dvb/frontend.h>
28 28
29struct tda1002x_config 29struct tda1002x_config {
30{
31 /* the demodulator's i2c address */ 30 /* the demodulator's i2c address */
32 u8 demod_address; 31 u8 demod_address;
33 u8 invert; 32 u8 invert;
34}; 33};
35 34
35enum tda10023_output_mode {
36 TDA10023_OUTPUT_MODE_PARALLEL_A = 0xe0,
37 TDA10023_OUTPUT_MODE_PARALLEL_B = 0xa1,
38 TDA10023_OUTPUT_MODE_PARALLEL_C = 0xa0,
39 TDA10023_OUTPUT_MODE_SERIAL, /* TODO: not implemented */
40};
41
42struct tda10023_config {
43 /* the demodulator's i2c address */
44 u8 demod_address;
45 u8 invert;
46
47 /* clock settings */
48 u32 xtal; /* defaults: 28920000 */
49 u8 pll_m; /* defaults: 8 */
50 u8 pll_p; /* defaults: 4 */
51 u8 pll_n; /* defaults: 1 */
52
53 /* MPEG2 TS output mode */
54 u8 output_mode;
55
56 /* input freq offset + baseband conversion type */
57 u16 deltaf;
58};
59
36#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) 60#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
37extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, 61extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
38 struct i2c_adapter* i2c, u8 pwm); 62 struct i2c_adapter* i2c, u8 pwm);
@@ -45,12 +69,15 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config*
45} 69}
46#endif // CONFIG_DVB_TDA10021 70#endif // CONFIG_DVB_TDA10021
47 71
48#if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE)) 72#if defined(CONFIG_DVB_TDA10023) || \
49extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, 73 (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
50 struct i2c_adapter* i2c, u8 pwm); 74extern struct dvb_frontend *tda10023_attach(
75 const struct tda10023_config *config,
76 struct i2c_adapter *i2c, u8 pwm);
51#else 77#else
52static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, 78static inline struct dvb_frontend *tda10023_attach(
53 struct i2c_adapter* i2c, u8 pwm) 79 const struct tda10023_config *config,
80 struct i2c_adapter *i2c, u8 pwm)
54{ 81{
55 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 82 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
56 return NULL; 83 return NULL;