diff options
Diffstat (limited to 'drivers/media/dvb/frontends/stv6110x.c')
-rw-r--r-- | drivers/media/dvb/frontends/stv6110x.c | 188 |
1 files changed, 120 insertions, 68 deletions
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c index bcfcb652464..f931ed07e92 100644 --- a/drivers/media/dvb/frontends/stv6110x.c +++ b/drivers/media/dvb/frontends/stv6110x.c | |||
@@ -35,8 +35,6 @@ static unsigned int verbose; | |||
35 | module_param(verbose, int, 0644); | 35 | module_param(verbose, int, 0644); |
36 | MODULE_PARM_DESC(verbose, "Set Verbosity level"); | 36 | MODULE_PARM_DESC(verbose, "Set Verbosity level"); |
37 | 37 | ||
38 | static u8 stv6110x_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; | ||
39 | |||
40 | static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) | 38 | static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) |
41 | { | 39 | { |
42 | int ret; | 40 | int ret; |
@@ -58,12 +56,23 @@ static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) | |||
58 | return 0; | 56 | return 0; |
59 | } | 57 | } |
60 | 58 | ||
61 | static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) | 59 | static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len) |
62 | { | 60 | { |
63 | int ret; | 61 | int ret; |
64 | const struct stv6110x_config *config = stv6110x->config; | 62 | const struct stv6110x_config *config = stv6110x->config; |
65 | u8 buf[] = { reg, data }; | 63 | u8 buf[len + 1]; |
66 | struct i2c_msg msg = { .addr = config->addr, .flags = 0, . buf = buf, .len = 2 }; | 64 | struct i2c_msg msg = { |
65 | .addr = config->addr, | ||
66 | .flags = 0, | ||
67 | .buf = buf, | ||
68 | .len = len + 1 | ||
69 | }; | ||
70 | |||
71 | if (start + len > 8) | ||
72 | return -EINVAL; | ||
73 | |||
74 | buf[0] = start; | ||
75 | memcpy(&buf[1], data, len); | ||
67 | 76 | ||
68 | ret = i2c_transfer(stv6110x->i2c, &msg, 1); | 77 | ret = i2c_transfer(stv6110x->i2c, &msg, 1); |
69 | if (ret != 1) { | 78 | if (ret != 1) { |
@@ -74,18 +83,21 @@ static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) | |||
74 | return 0; | 83 | return 0; |
75 | } | 84 | } |
76 | 85 | ||
86 | static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) | ||
87 | { | ||
88 | return stv6110x_write_regs(stv6110x, reg, &data, 1); | ||
89 | } | ||
90 | |||
77 | static int stv6110x_init(struct dvb_frontend *fe) | 91 | static int stv6110x_init(struct dvb_frontend *fe) |
78 | { | 92 | { |
79 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 93 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
80 | int ret; | 94 | int ret; |
81 | u8 i; | ||
82 | 95 | ||
83 | for (i = 0; i < ARRAY_SIZE(stv6110x_regs); i++) { | 96 | ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs, |
84 | ret = stv6110x_write_reg(stv6110x, i, stv6110x_regs[i]); | 97 | ARRAY_SIZE(stv6110x->regs)); |
85 | if (ret < 0) { | 98 | if (ret < 0) { |
86 | dprintk(FE_ERROR, 1, "Initialization failed"); | 99 | dprintk(FE_ERROR, 1, "Initialization failed"); |
87 | return -1; | 100 | return -1; |
88 | } | ||
89 | } | 101 | } |
90 | 102 | ||
91 | return 0; | 103 | return 0; |
@@ -98,23 +110,23 @@ static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) | |||
98 | s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000; | 110 | s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000; |
99 | u8 i; | 111 | u8 i; |
100 | 112 | ||
101 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); | 113 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); |
102 | 114 | ||
103 | if (frequency <= 1023000) { | 115 | if (frequency <= 1023000) { |
104 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); | 116 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); |
105 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); | 117 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); |
106 | pVal = 40; | 118 | pVal = 40; |
107 | } else if (frequency <= 1300000) { | 119 | } else if (frequency <= 1300000) { |
108 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); | 120 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); |
109 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); | 121 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); |
110 | pVal = 40; | 122 | pVal = 40; |
111 | } else if (frequency <= 2046000) { | 123 | } else if (frequency <= 2046000) { |
112 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); | 124 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); |
113 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); | 125 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); |
114 | pVal = 20; | 126 | pVal = 20; |
115 | } else { | 127 | } else { |
116 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); | 128 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); |
117 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); | 129 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); |
118 | pVal = 20; | 130 | pVal = 20; |
119 | } | 131 | } |
120 | 132 | ||
@@ -130,21 +142,21 @@ static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) | |||
130 | divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; | 142 | divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; |
131 | divider = (divider + 5) / 10; | 143 | divider = (divider + 5) / 10; |
132 | 144 | ||
133 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt); | 145 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt); |
134 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider)); | 146 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider)); |
135 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider)); | 147 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider)); |
136 | 148 | ||
137 | /* VCO Auto calibration */ | 149 | /* VCO Auto calibration */ |
138 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1); | 150 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1); |
139 | 151 | ||
140 | stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]); | 152 | stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]); |
141 | stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x_regs[STV6110x_TNG1]); | 153 | stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]); |
142 | stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x_regs[STV6110x_TNG0]); | 154 | stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]); |
143 | stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]); | 155 | stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]); |
144 | 156 | ||
145 | for (i = 0; i < TRIALS; i++) { | 157 | for (i = 0; i < TRIALS; i++) { |
146 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); | 158 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); |
147 | if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x_regs[STV6110x_STAT1])) | 159 | if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1])) |
148 | break; | 160 | break; |
149 | msleep(1); | 161 | msleep(1); |
150 | } | 162 | } |
@@ -156,14 +168,14 @@ static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
156 | { | 168 | { |
157 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 169 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
158 | 170 | ||
159 | stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x_regs[STV6110x_TNG1]); | 171 | stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]); |
160 | stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x_regs[STV6110x_TNG0]); | 172 | stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]); |
161 | 173 | ||
162 | *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x_regs[STV6110x_TNG1]), | 174 | *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]), |
163 | STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x_regs[STV6110x_TNG0]))) * REFCLOCK_kHz; | 175 | STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz; |
164 | 176 | ||
165 | *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x_regs[STV6110x_TNG1]) + | 177 | *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) + |
166 | STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x_regs[STV6110x_TNG1]))); | 178 | STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1]))); |
167 | 179 | ||
168 | *frequency >>= 2; | 180 | *frequency >>= 2; |
169 | 181 | ||
@@ -179,27 +191,27 @@ static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) | |||
179 | halfbw = bandwidth >> 1; | 191 | halfbw = bandwidth >> 1; |
180 | 192 | ||
181 | if (halfbw > 36000000) | 193 | if (halfbw > 36000000) |
182 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */ | 194 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */ |
183 | else if (halfbw < 5000000) | 195 | else if (halfbw < 5000000) |
184 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */ | 196 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */ |
185 | else | 197 | else |
186 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */ | 198 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */ |
187 | 199 | ||
188 | 200 | ||
189 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */ | 201 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */ |
190 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */ | 202 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */ |
191 | 203 | ||
192 | stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]); | 204 | stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]); |
193 | stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x_regs[STV6110x_STAT1]); | 205 | stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]); |
194 | 206 | ||
195 | for (i = 0; i < TRIALS; i++) { | 207 | for (i = 0; i < TRIALS; i++) { |
196 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); | 208 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); |
197 | if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x_regs[STV6110x_STAT1])) | 209 | if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1])) |
198 | break; | 210 | break; |
199 | msleep(1); | 211 | msleep(1); |
200 | } | 212 | } |
201 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */ | 213 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */ |
202 | stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x_regs[STV6110x_CTRL3]); | 214 | stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]); |
203 | 215 | ||
204 | return 0; | 216 | return 0; |
205 | } | 217 | } |
@@ -208,8 +220,8 @@ static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
208 | { | 220 | { |
209 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 221 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
210 | 222 | ||
211 | stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x_regs[STV6110x_CTRL3]); | 223 | stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]); |
212 | *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x_regs[STV6110x_CTRL3]) + 5) * 2000000; | 224 | *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000; |
213 | 225 | ||
214 | return 0; | 226 | return 0; |
215 | } | 227 | } |
@@ -222,20 +234,20 @@ static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock) | |||
222 | switch (refclock) { | 234 | switch (refclock) { |
223 | default: | 235 | default: |
224 | case 1: | 236 | case 1: |
225 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); | 237 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); |
226 | break; | 238 | break; |
227 | case 2: | 239 | case 2: |
228 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); | 240 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); |
229 | break; | 241 | break; |
230 | case 4: | 242 | case 4: |
231 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); | 243 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); |
232 | break; | 244 | break; |
233 | case 8: | 245 | case 8: |
234 | case 0: | 246 | case 0: |
235 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); | 247 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); |
236 | break; | 248 | break; |
237 | } | 249 | } |
238 | stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]); | 250 | stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]); |
239 | 251 | ||
240 | return 0; | 252 | return 0; |
241 | } | 253 | } |
@@ -244,8 +256,8 @@ static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain) | |||
244 | { | 256 | { |
245 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 257 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
246 | 258 | ||
247 | stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x_regs[STV6110x_CTRL2]); | 259 | stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]); |
248 | *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x_regs[STV6110x_CTRL2]); | 260 | *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]); |
249 | 261 | ||
250 | return 0; | 262 | return 0; |
251 | } | 263 | } |
@@ -254,8 +266,8 @@ static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain) | |||
254 | { | 266 | { |
255 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 267 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
256 | 268 | ||
257 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2); | 269 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2); |
258 | stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x_regs[STV6110x_CTRL2]); | 270 | stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]); |
259 | 271 | ||
260 | return 0; | 272 | return 0; |
261 | } | 273 | } |
@@ -267,19 +279,19 @@ static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode) | |||
267 | 279 | ||
268 | switch (mode) { | 280 | switch (mode) { |
269 | case TUNER_SLEEP: | 281 | case TUNER_SLEEP: |
270 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 0); | 282 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0); |
271 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 0); | 283 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0); |
272 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 0); | 284 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0); |
273 | break; | 285 | break; |
274 | 286 | ||
275 | case TUNER_WAKE: | 287 | case TUNER_WAKE: |
276 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_SYN, 1); | 288 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1); |
277 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_RX, 1); | 289 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1); |
278 | STV6110x_SETFIELD(stv6110x_regs[STV6110x_CTRL1], CTRL1_LPT, 1); | 290 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1); |
279 | break; | 291 | break; |
280 | } | 292 | } |
281 | 293 | ||
282 | ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x_regs[STV6110x_CTRL1]); | 294 | ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]); |
283 | if (ret < 0) { | 295 | if (ret < 0) { |
284 | dprintk(FE_ERROR, 1, "I/O Error"); | 296 | dprintk(FE_ERROR, 1, "I/O Error"); |
285 | return -EIO; | 297 | return -EIO; |
@@ -297,9 +309,9 @@ static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) | |||
297 | { | 309 | { |
298 | struct stv6110x_state *stv6110x = fe->tuner_priv; | 310 | struct stv6110x_state *stv6110x = fe->tuner_priv; |
299 | 311 | ||
300 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x_regs[STV6110x_STAT1]); | 312 | stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); |
301 | 313 | ||
302 | if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x_regs[STV6110x_STAT1])) | 314 | if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1])) |
303 | *status = TUNER_PHASELOCKED; | 315 | *status = TUNER_PHASELOCKED; |
304 | else | 316 | else |
305 | *status = 0; | 317 | *status = 0; |
@@ -349,6 +361,8 @@ struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | |||
349 | struct i2c_adapter *i2c) | 361 | struct i2c_adapter *i2c) |
350 | { | 362 | { |
351 | struct stv6110x_state *stv6110x; | 363 | struct stv6110x_state *stv6110x; |
364 | u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; | ||
365 | int ret; | ||
352 | 366 | ||
353 | stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); | 367 | stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); |
354 | if (stv6110x == NULL) | 368 | if (stv6110x == NULL) |
@@ -357,6 +371,44 @@ struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | |||
357 | stv6110x->i2c = i2c; | 371 | stv6110x->i2c = i2c; |
358 | stv6110x->config = config; | 372 | stv6110x->config = config; |
359 | stv6110x->devctl = &stv6110x_ctl; | 373 | stv6110x->devctl = &stv6110x_ctl; |
374 | memcpy(stv6110x->regs, default_regs, 8); | ||
375 | |||
376 | /* setup divider */ | ||
377 | switch (stv6110x->config->clk_div) { | ||
378 | default: | ||
379 | case 1: | ||
380 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); | ||
381 | break; | ||
382 | case 2: | ||
383 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); | ||
384 | break; | ||
385 | case 4: | ||
386 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); | ||
387 | break; | ||
388 | case 8: | ||
389 | case 0: | ||
390 | STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); | ||
391 | break; | ||
392 | } | ||
393 | |||
394 | if (fe->ops.i2c_gate_ctrl) { | ||
395 | ret = fe->ops.i2c_gate_ctrl(fe, 1); | ||
396 | if (ret < 0) | ||
397 | goto error; | ||
398 | } | ||
399 | |||
400 | ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs, | ||
401 | ARRAY_SIZE(stv6110x->regs)); | ||
402 | if (ret < 0) { | ||
403 | dprintk(FE_ERROR, 1, "Initialization failed"); | ||
404 | goto error; | ||
405 | } | ||
406 | |||
407 | if (fe->ops.i2c_gate_ctrl) { | ||
408 | ret = fe->ops.i2c_gate_ctrl(fe, 0); | ||
409 | if (ret < 0) | ||
410 | goto error; | ||
411 | } | ||
360 | 412 | ||
361 | fe->tuner_priv = stv6110x; | 413 | fe->tuner_priv = stv6110x; |
362 | fe->ops.tuner_ops = stv6110x_ops; | 414 | fe->ops.tuner_ops = stv6110x_ops; |