diff options
-rw-r--r-- | drivers/media/dvb/frontends/tda18271-fe.c | 44 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda18271-priv.h | 1 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/tda18271.h | 8 |
3 files changed, 44 insertions, 9 deletions
diff --git a/drivers/media/dvb/frontends/tda18271-fe.c b/drivers/media/dvb/frontends/tda18271-fe.c index 46905a773e46..5b1cb7f5745c 100644 --- a/drivers/media/dvb/frontends/tda18271-fe.c +++ b/drivers/media/dvb/frontends/tda18271-fe.c | |||
@@ -36,6 +36,15 @@ static LIST_HEAD(hybrid_tuner_instance_list); | |||
36 | 36 | ||
37 | /*---------------------------------------------------------------------*/ | 37 | /*---------------------------------------------------------------------*/ |
38 | 38 | ||
39 | static inline int charge_pump_source(struct dvb_frontend *fe, int force) | ||
40 | { | ||
41 | struct tda18271_priv *priv = fe->tuner_priv; | ||
42 | return tda18271_charge_pump_source(fe, | ||
43 | (priv->role == TDA18271_SLAVE) ? | ||
44 | TDA18271_CAL_PLL : | ||
45 | TDA18271_MAIN_PLL, force); | ||
46 | } | ||
47 | |||
39 | static int tda18271_channel_configuration(struct dvb_frontend *fe, | 48 | static int tda18271_channel_configuration(struct dvb_frontend *fe, |
40 | struct tda18271_std_map_item *map, | 49 | struct tda18271_std_map_item *map, |
41 | u32 freq, u32 bw) | 50 | u32 freq, u32 bw) |
@@ -97,8 +106,14 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, | |||
97 | 106 | ||
98 | /* dual tuner and agc1 extra configuration */ | 107 | /* dual tuner and agc1 extra configuration */ |
99 | 108 | ||
100 | /* main vco when Master, cal vco when slave */ | 109 | switch (priv->role) { |
101 | regs[R_EB1] |= 0x04; /* FIXME: assumes master */ | 110 | case TDA18271_MASTER: |
111 | regs[R_EB1] |= 0x04; /* main vco */ | ||
112 | break; | ||
113 | case TDA18271_SLAVE: | ||
114 | regs[R_EB1] &= ~0x04; /* cal vco */ | ||
115 | break; | ||
116 | } | ||
102 | 117 | ||
103 | /* agc1 always active */ | 118 | /* agc1 always active */ |
104 | regs[R_EB1] &= ~0x02; | 119 | regs[R_EB1] &= ~0x02; |
@@ -112,19 +127,29 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, | |||
112 | 127 | ||
113 | N = map->if_freq * 1000 + freq; | 128 | N = map->if_freq * 1000 + freq; |
114 | 129 | ||
115 | /* FIXME: assumes master */ | 130 | switch (priv->role) { |
116 | tda18271_calc_main_pll(fe, N); | 131 | case TDA18271_MASTER: |
117 | tda18271_write_regs(fe, R_MPD, 4); | 132 | tda18271_calc_main_pll(fe, N); |
133 | tda18271_write_regs(fe, R_MPD, 4); | ||
134 | break; | ||
135 | case TDA18271_SLAVE: | ||
136 | tda18271_calc_cal_pll(fe, N); | ||
137 | tda18271_write_regs(fe, R_CPD, 4); | ||
138 | |||
139 | regs[R_MPD] = regs[R_CPD] & 0x7f; | ||
140 | tda18271_write_regs(fe, R_MPD, 1); | ||
141 | break; | ||
142 | } | ||
118 | 143 | ||
119 | tda18271_write_regs(fe, R_TM, 7); | 144 | tda18271_write_regs(fe, R_TM, 7); |
120 | 145 | ||
121 | /* main pll charge pump source */ | 146 | /* force charge pump source */ |
122 | tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1); | 147 | charge_pump_source(fe, 1); |
123 | 148 | ||
124 | msleep(1); | 149 | msleep(1); |
125 | 150 | ||
126 | /* normal operation for the main pll */ | 151 | /* return pll to normal operation */ |
127 | tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0); | 152 | charge_pump_source(fe, 0); |
128 | 153 | ||
129 | msleep(20); | 154 | msleep(20); |
130 | 155 | ||
@@ -1058,6 +1083,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, | |||
1058 | case 1: | 1083 | case 1: |
1059 | /* new tuner instance */ | 1084 | /* new tuner instance */ |
1060 | priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; | 1085 | priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; |
1086 | priv->role = (cfg) ? cfg->role : TDA18271_MASTER; | ||
1061 | priv->cal_initialized = false; | 1087 | priv->cal_initialized = false; |
1062 | mutex_init(&priv->lock); | 1088 | mutex_init(&priv->lock); |
1063 | 1089 | ||
diff --git a/drivers/media/dvb/frontends/tda18271-priv.h b/drivers/media/dvb/frontends/tda18271-priv.h index 2a37f794e1b6..4b153bc557fe 100644 --- a/drivers/media/dvb/frontends/tda18271-priv.h +++ b/drivers/media/dvb/frontends/tda18271-priv.h | |||
@@ -110,6 +110,7 @@ struct tda18271_priv { | |||
110 | struct tuner_i2c_props i2c_props; | 110 | struct tuner_i2c_props i2c_props; |
111 | 111 | ||
112 | enum tda18271_mode mode; | 112 | enum tda18271_mode mode; |
113 | enum tda18271_role role; | ||
113 | enum tda18271_i2c_gate gate; | 114 | enum tda18271_i2c_gate gate; |
114 | enum tda18271_ver id; | 115 | enum tda18271_ver id; |
115 | 116 | ||
diff --git a/drivers/media/dvb/frontends/tda18271.h b/drivers/media/dvb/frontends/tda18271.h index 44d41dce9e10..b547318c951b 100644 --- a/drivers/media/dvb/frontends/tda18271.h +++ b/drivers/media/dvb/frontends/tda18271.h | |||
@@ -56,6 +56,11 @@ struct tda18271_std_map { | |||
56 | struct tda18271_std_map_item qam_8; | 56 | struct tda18271_std_map_item qam_8; |
57 | }; | 57 | }; |
58 | 58 | ||
59 | enum tda18271_role { | ||
60 | TDA18271_MASTER = 0, | ||
61 | TDA18271_SLAVE, | ||
62 | }; | ||
63 | |||
59 | enum tda18271_i2c_gate { | 64 | enum tda18271_i2c_gate { |
60 | TDA18271_GATE_AUTO = 0, | 65 | TDA18271_GATE_AUTO = 0, |
61 | TDA18271_GATE_ANALOG, | 66 | TDA18271_GATE_ANALOG, |
@@ -66,6 +71,9 @@ struct tda18271_config { | |||
66 | /* override default if freq / std settings (optional) */ | 71 | /* override default if freq / std settings (optional) */ |
67 | struct tda18271_std_map *std_map; | 72 | struct tda18271_std_map *std_map; |
68 | 73 | ||
74 | /* master / slave tuner: master uses main pll, slave uses cal pll */ | ||
75 | enum tda18271_role role; | ||
76 | |||
69 | /* use i2c gate provided by analog or digital demod */ | 77 | /* use i2c gate provided by analog or digital demod */ |
70 | enum tda18271_i2c_gate gate; | 78 | enum tda18271_i2c_gate gate; |
71 | 79 | ||