diff options
Diffstat (limited to 'drivers/media/tuners/m88ts2022.c')
-rw-r--r-- | drivers/media/tuners/m88ts2022.c | 355 |
1 files changed, 129 insertions, 226 deletions
diff --git a/drivers/media/tuners/m88ts2022.c b/drivers/media/tuners/m88ts2022.c index 40c42dec721b..caa542346891 100644 --- a/drivers/media/tuners/m88ts2022.c +++ b/drivers/media/tuners/m88ts2022.c | |||
@@ -18,120 +18,11 @@ | |||
18 | 18 | ||
19 | #include "m88ts2022_priv.h" | 19 | #include "m88ts2022_priv.h" |
20 | 20 | ||
21 | /* write multiple registers */ | 21 | static int m88ts2022_cmd(struct m88ts2022_dev *dev, int op, int sleep, u8 reg, |
22 | static int m88ts2022_wr_regs(struct m88ts2022_priv *priv, | 22 | u8 mask, u8 val, u8 *reg_val) |
23 | u8 reg, const u8 *val, int len) | ||
24 | { | 23 | { |
25 | #define MAX_WR_LEN 3 | ||
26 | #define MAX_WR_XFER_LEN (MAX_WR_LEN + 1) | ||
27 | int ret; | ||
28 | u8 buf[MAX_WR_XFER_LEN]; | ||
29 | struct i2c_msg msg[1] = { | ||
30 | { | ||
31 | .addr = priv->client->addr, | ||
32 | .flags = 0, | ||
33 | .len = 1 + len, | ||
34 | .buf = buf, | ||
35 | } | ||
36 | }; | ||
37 | |||
38 | if (WARN_ON(len > MAX_WR_LEN)) | ||
39 | return -EINVAL; | ||
40 | |||
41 | buf[0] = reg; | ||
42 | memcpy(&buf[1], val, len); | ||
43 | |||
44 | ret = i2c_transfer(priv->client->adapter, msg, 1); | ||
45 | if (ret == 1) { | ||
46 | ret = 0; | ||
47 | } else { | ||
48 | dev_warn(&priv->client->dev, | ||
49 | "%s: i2c wr failed=%d reg=%02x len=%d\n", | ||
50 | KBUILD_MODNAME, ret, reg, len); | ||
51 | ret = -EREMOTEIO; | ||
52 | } | ||
53 | |||
54 | return ret; | ||
55 | } | ||
56 | |||
57 | /* read multiple registers */ | ||
58 | static int m88ts2022_rd_regs(struct m88ts2022_priv *priv, u8 reg, | ||
59 | u8 *val, int len) | ||
60 | { | ||
61 | #define MAX_RD_LEN 1 | ||
62 | #define MAX_RD_XFER_LEN (MAX_RD_LEN) | ||
63 | int ret; | ||
64 | u8 buf[MAX_RD_XFER_LEN]; | ||
65 | struct i2c_msg msg[2] = { | ||
66 | { | ||
67 | .addr = priv->client->addr, | ||
68 | .flags = 0, | ||
69 | .len = 1, | ||
70 | .buf = ®, | ||
71 | }, { | ||
72 | .addr = priv->client->addr, | ||
73 | .flags = I2C_M_RD, | ||
74 | .len = len, | ||
75 | .buf = buf, | ||
76 | } | ||
77 | }; | ||
78 | |||
79 | if (WARN_ON(len > MAX_RD_LEN)) | ||
80 | return -EINVAL; | ||
81 | |||
82 | ret = i2c_transfer(priv->client->adapter, msg, 2); | ||
83 | if (ret == 2) { | ||
84 | memcpy(val, buf, len); | ||
85 | ret = 0; | ||
86 | } else { | ||
87 | dev_warn(&priv->client->dev, | ||
88 | "%s: i2c rd failed=%d reg=%02x len=%d\n", | ||
89 | KBUILD_MODNAME, ret, reg, len); | ||
90 | ret = -EREMOTEIO; | ||
91 | } | ||
92 | |||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | /* write single register */ | ||
97 | static int m88ts2022_wr_reg(struct m88ts2022_priv *priv, u8 reg, u8 val) | ||
98 | { | ||
99 | return m88ts2022_wr_regs(priv, reg, &val, 1); | ||
100 | } | ||
101 | |||
102 | /* read single register */ | ||
103 | static int m88ts2022_rd_reg(struct m88ts2022_priv *priv, u8 reg, u8 *val) | ||
104 | { | ||
105 | return m88ts2022_rd_regs(priv, reg, val, 1); | ||
106 | } | ||
107 | |||
108 | /* write single register with mask */ | ||
109 | static int m88ts2022_wr_reg_mask(struct m88ts2022_priv *priv, | ||
110 | u8 reg, u8 val, u8 mask) | ||
111 | { | ||
112 | int ret; | ||
113 | u8 u8tmp; | ||
114 | |||
115 | /* no need for read if whole reg is written */ | ||
116 | if (mask != 0xff) { | ||
117 | ret = m88ts2022_rd_regs(priv, reg, &u8tmp, 1); | ||
118 | if (ret) | ||
119 | return ret; | ||
120 | |||
121 | val &= mask; | ||
122 | u8tmp &= ~mask; | ||
123 | val |= u8tmp; | ||
124 | } | ||
125 | |||
126 | return m88ts2022_wr_regs(priv, reg, &val, 1); | ||
127 | } | ||
128 | |||
129 | static int m88ts2022_cmd(struct dvb_frontend *fe, | ||
130 | int op, int sleep, u8 reg, u8 mask, u8 val, u8 *reg_val) | ||
131 | { | ||
132 | struct m88ts2022_priv *priv = fe->tuner_priv; | ||
133 | int ret, i; | 24 | int ret, i; |
134 | u8 u8tmp; | 25 | unsigned int utmp; |
135 | struct m88ts2022_reg_val reg_vals[] = { | 26 | struct m88ts2022_reg_val reg_vals[] = { |
136 | {0x51, 0x1f - op}, | 27 | {0x51, 0x1f - op}, |
137 | {0x51, 0x1f}, | 28 | {0x51, 0x1f}, |
@@ -140,12 +31,12 @@ static int m88ts2022_cmd(struct dvb_frontend *fe, | |||
140 | }; | 31 | }; |
141 | 32 | ||
142 | for (i = 0; i < 2; i++) { | 33 | for (i = 0; i < 2; i++) { |
143 | dev_dbg(&priv->client->dev, | 34 | dev_dbg(&dev->client->dev, |
144 | "%s: i=%d op=%02x reg=%02x mask=%02x val=%02x\n", | 35 | "i=%d op=%02x reg=%02x mask=%02x val=%02x\n", |
145 | __func__, i, op, reg, mask, val); | 36 | i, op, reg, mask, val); |
146 | 37 | ||
147 | for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { | 38 | for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { |
148 | ret = m88ts2022_wr_reg(priv, reg_vals[i].reg, | 39 | ret = regmap_write(dev->regmap, reg_vals[i].reg, |
149 | reg_vals[i].val); | 40 | reg_vals[i].val); |
150 | if (ret) | 41 | if (ret) |
151 | goto err; | 42 | goto err; |
@@ -153,37 +44,38 @@ static int m88ts2022_cmd(struct dvb_frontend *fe, | |||
153 | 44 | ||
154 | usleep_range(sleep * 1000, sleep * 10000); | 45 | usleep_range(sleep * 1000, sleep * 10000); |
155 | 46 | ||
156 | ret = m88ts2022_rd_reg(priv, reg, &u8tmp); | 47 | ret = regmap_read(dev->regmap, reg, &utmp); |
157 | if (ret) | 48 | if (ret) |
158 | goto err; | 49 | goto err; |
159 | 50 | ||
160 | if ((u8tmp & mask) != val) | 51 | if ((utmp & mask) != val) |
161 | break; | 52 | break; |
162 | } | 53 | } |
163 | 54 | ||
164 | if (reg_val) | 55 | if (reg_val) |
165 | *reg_val = u8tmp; | 56 | *reg_val = utmp; |
166 | err: | 57 | err: |
167 | return ret; | 58 | return ret; |
168 | } | 59 | } |
169 | 60 | ||
170 | static int m88ts2022_set_params(struct dvb_frontend *fe) | 61 | static int m88ts2022_set_params(struct dvb_frontend *fe) |
171 | { | 62 | { |
172 | struct m88ts2022_priv *priv = fe->tuner_priv; | 63 | struct m88ts2022_dev *dev = fe->tuner_priv; |
173 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 64 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
174 | int ret; | 65 | int ret; |
175 | unsigned int frequency_khz, frequency_offset_khz, f_3db_hz; | 66 | unsigned int utmp, frequency_khz, frequency_offset_khz, f_3db_hz; |
176 | unsigned int f_ref_khz, f_vco_khz, div_ref, div_out, pll_n, gdiv28; | 67 | unsigned int f_ref_khz, f_vco_khz, div_ref, div_out, pll_n, gdiv28; |
177 | u8 buf[3], u8tmp, cap_code, lpf_gm, lpf_mxdiv, div_max, div_min; | 68 | u8 buf[3], u8tmp, cap_code, lpf_gm, lpf_mxdiv, div_max, div_min; |
178 | u16 u16tmp; | 69 | u16 u16tmp; |
179 | dev_dbg(&priv->client->dev, | 70 | |
180 | "%s: frequency=%d symbol_rate=%d rolloff=%d\n", | 71 | dev_dbg(&dev->client->dev, |
181 | __func__, c->frequency, c->symbol_rate, c->rolloff); | 72 | "frequency=%d symbol_rate=%d rolloff=%d\n", |
73 | c->frequency, c->symbol_rate, c->rolloff); | ||
182 | /* | 74 | /* |
183 | * Integer-N PLL synthesizer | 75 | * Integer-N PLL synthesizer |
184 | * kHz is used for all calculations to keep calculations within 32-bit | 76 | * kHz is used for all calculations to keep calculations within 32-bit |
185 | */ | 77 | */ |
186 | f_ref_khz = DIV_ROUND_CLOSEST(priv->cfg.clock, 1000); | 78 | f_ref_khz = DIV_ROUND_CLOSEST(dev->cfg.clock, 1000); |
187 | div_ref = DIV_ROUND_CLOSEST(f_ref_khz, 2000); | 79 | div_ref = DIV_ROUND_CLOSEST(f_ref_khz, 2000); |
188 | 80 | ||
189 | if (c->symbol_rate < 5000000) | 81 | if (c->symbol_rate < 5000000) |
@@ -203,14 +95,14 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) | |||
203 | 95 | ||
204 | buf[0] = u8tmp; | 96 | buf[0] = u8tmp; |
205 | buf[1] = 0x40; | 97 | buf[1] = 0x40; |
206 | ret = m88ts2022_wr_regs(priv, 0x10, buf, 2); | 98 | ret = regmap_bulk_write(dev->regmap, 0x10, buf, 2); |
207 | if (ret) | 99 | if (ret) |
208 | goto err; | 100 | goto err; |
209 | 101 | ||
210 | f_vco_khz = frequency_khz * div_out; | 102 | f_vco_khz = frequency_khz * div_out; |
211 | pll_n = f_vco_khz * div_ref / f_ref_khz; | 103 | pll_n = f_vco_khz * div_ref / f_ref_khz; |
212 | pll_n += pll_n % 2; | 104 | pll_n += pll_n % 2; |
213 | priv->frequency_khz = pll_n * f_ref_khz / div_ref / div_out; | 105 | dev->frequency_khz = pll_n * f_ref_khz / div_ref / div_out; |
214 | 106 | ||
215 | if (pll_n < 4095) | 107 | if (pll_n < 4095) |
216 | u16tmp = pll_n - 1024; | 108 | u16tmp = pll_n - 1024; |
@@ -222,88 +114,87 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) | |||
222 | buf[0] = (u16tmp >> 8) & 0x3f; | 114 | buf[0] = (u16tmp >> 8) & 0x3f; |
223 | buf[1] = (u16tmp >> 0) & 0xff; | 115 | buf[1] = (u16tmp >> 0) & 0xff; |
224 | buf[2] = div_ref - 8; | 116 | buf[2] = div_ref - 8; |
225 | ret = m88ts2022_wr_regs(priv, 0x01, buf, 3); | 117 | ret = regmap_bulk_write(dev->regmap, 0x01, buf, 3); |
226 | if (ret) | 118 | if (ret) |
227 | goto err; | 119 | goto err; |
228 | 120 | ||
229 | dev_dbg(&priv->client->dev, | 121 | dev_dbg(&dev->client->dev, |
230 | "%s: frequency=%u offset=%d f_vco_khz=%u pll_n=%u div_ref=%u div_out=%u\n", | 122 | "frequency=%u offset=%d f_vco_khz=%u pll_n=%u div_ref=%u div_out=%u\n", |
231 | __func__, priv->frequency_khz, | 123 | dev->frequency_khz, dev->frequency_khz - c->frequency, |
232 | priv->frequency_khz - c->frequency, f_vco_khz, pll_n, | 124 | f_vco_khz, pll_n, div_ref, div_out); |
233 | div_ref, div_out); | ||
234 | 125 | ||
235 | ret = m88ts2022_cmd(fe, 0x10, 5, 0x15, 0x40, 0x00, NULL); | 126 | ret = m88ts2022_cmd(dev, 0x10, 5, 0x15, 0x40, 0x00, NULL); |
236 | if (ret) | 127 | if (ret) |
237 | goto err; | 128 | goto err; |
238 | 129 | ||
239 | ret = m88ts2022_rd_reg(priv, 0x14, &u8tmp); | 130 | ret = regmap_read(dev->regmap, 0x14, &utmp); |
240 | if (ret) | 131 | if (ret) |
241 | goto err; | 132 | goto err; |
242 | 133 | ||
243 | u8tmp &= 0x7f; | 134 | utmp &= 0x7f; |
244 | if (u8tmp < 64) { | 135 | if (utmp < 64) { |
245 | ret = m88ts2022_wr_reg_mask(priv, 0x10, 0x80, 0x80); | 136 | ret = regmap_update_bits(dev->regmap, 0x10, 0x80, 0x80); |
246 | if (ret) | 137 | if (ret) |
247 | goto err; | 138 | goto err; |
248 | 139 | ||
249 | ret = m88ts2022_wr_reg(priv, 0x11, 0x6f); | 140 | ret = regmap_write(dev->regmap, 0x11, 0x6f); |
250 | if (ret) | 141 | if (ret) |
251 | goto err; | 142 | goto err; |
252 | 143 | ||
253 | ret = m88ts2022_cmd(fe, 0x10, 5, 0x15, 0x40, 0x00, NULL); | 144 | ret = m88ts2022_cmd(dev, 0x10, 5, 0x15, 0x40, 0x00, NULL); |
254 | if (ret) | 145 | if (ret) |
255 | goto err; | 146 | goto err; |
256 | } | 147 | } |
257 | 148 | ||
258 | ret = m88ts2022_rd_reg(priv, 0x14, &u8tmp); | 149 | ret = regmap_read(dev->regmap, 0x14, &utmp); |
259 | if (ret) | 150 | if (ret) |
260 | goto err; | 151 | goto err; |
261 | 152 | ||
262 | u8tmp &= 0x1f; | 153 | utmp &= 0x1f; |
263 | if (u8tmp > 19) { | 154 | if (utmp > 19) { |
264 | ret = m88ts2022_wr_reg_mask(priv, 0x10, 0x00, 0x02); | 155 | ret = regmap_update_bits(dev->regmap, 0x10, 0x02, 0x00); |
265 | if (ret) | 156 | if (ret) |
266 | goto err; | 157 | goto err; |
267 | } | 158 | } |
268 | 159 | ||
269 | ret = m88ts2022_cmd(fe, 0x08, 5, 0x3c, 0xff, 0x00, NULL); | 160 | ret = m88ts2022_cmd(dev, 0x08, 5, 0x3c, 0xff, 0x00, NULL); |
270 | if (ret) | 161 | if (ret) |
271 | goto err; | 162 | goto err; |
272 | 163 | ||
273 | ret = m88ts2022_wr_reg(priv, 0x25, 0x00); | 164 | ret = regmap_write(dev->regmap, 0x25, 0x00); |
274 | if (ret) | 165 | if (ret) |
275 | goto err; | 166 | goto err; |
276 | 167 | ||
277 | ret = m88ts2022_wr_reg(priv, 0x27, 0x70); | 168 | ret = regmap_write(dev->regmap, 0x27, 0x70); |
278 | if (ret) | 169 | if (ret) |
279 | goto err; | 170 | goto err; |
280 | 171 | ||
281 | ret = m88ts2022_wr_reg(priv, 0x41, 0x09); | 172 | ret = regmap_write(dev->regmap, 0x41, 0x09); |
282 | if (ret) | 173 | if (ret) |
283 | goto err; | 174 | goto err; |
284 | 175 | ||
285 | ret = m88ts2022_wr_reg(priv, 0x08, 0x0b); | 176 | ret = regmap_write(dev->regmap, 0x08, 0x0b); |
286 | if (ret) | 177 | if (ret) |
287 | goto err; | 178 | goto err; |
288 | 179 | ||
289 | /* filters */ | 180 | /* filters */ |
290 | gdiv28 = DIV_ROUND_CLOSEST(f_ref_khz * 1694U, 1000000U); | 181 | gdiv28 = DIV_ROUND_CLOSEST(f_ref_khz * 1694U, 1000000U); |
291 | 182 | ||
292 | ret = m88ts2022_wr_reg(priv, 0x04, gdiv28); | 183 | ret = regmap_write(dev->regmap, 0x04, gdiv28); |
293 | if (ret) | 184 | if (ret) |
294 | goto err; | 185 | goto err; |
295 | 186 | ||
296 | ret = m88ts2022_cmd(fe, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); | 187 | ret = m88ts2022_cmd(dev, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); |
297 | if (ret) | 188 | if (ret) |
298 | goto err; | 189 | goto err; |
299 | 190 | ||
300 | cap_code = u8tmp & 0x3f; | 191 | cap_code = u8tmp & 0x3f; |
301 | 192 | ||
302 | ret = m88ts2022_wr_reg(priv, 0x41, 0x0d); | 193 | ret = regmap_write(dev->regmap, 0x41, 0x0d); |
303 | if (ret) | 194 | if (ret) |
304 | goto err; | 195 | goto err; |
305 | 196 | ||
306 | ret = m88ts2022_cmd(fe, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); | 197 | ret = m88ts2022_cmd(dev, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); |
307 | if (ret) | 198 | if (ret) |
308 | goto err; | 199 | goto err; |
309 | 200 | ||
@@ -314,7 +205,7 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) | |||
314 | div_min = gdiv28 * 78 / 100; | 205 | div_min = gdiv28 * 78 / 100; |
315 | div_max = clamp_val(div_max, 0U, 63U); | 206 | div_max = clamp_val(div_max, 0U, 63U); |
316 | 207 | ||
317 | f_3db_hz = c->symbol_rate * 135UL / 200UL; | 208 | f_3db_hz = mult_frac(c->symbol_rate, 135, 200); |
318 | f_3db_hz += 2000000U + (frequency_offset_khz * 1000U); | 209 | f_3db_hz += 2000000U + (frequency_offset_khz * 1000U); |
319 | f_3db_hz = clamp(f_3db_hz, 7000000U, 40000000U); | 210 | f_3db_hz = clamp(f_3db_hz, 7000000U, 40000000U); |
320 | 211 | ||
@@ -327,25 +218,25 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) | |||
327 | lpf_mxdiv = DIV_ROUND_CLOSEST(++lpf_gm * LPF_COEFF * f_ref_khz, f_3db_hz); | 218 | lpf_mxdiv = DIV_ROUND_CLOSEST(++lpf_gm * LPF_COEFF * f_ref_khz, f_3db_hz); |
328 | lpf_mxdiv = clamp_val(lpf_mxdiv, 0U, div_max); | 219 | lpf_mxdiv = clamp_val(lpf_mxdiv, 0U, div_max); |
329 | 220 | ||
330 | ret = m88ts2022_wr_reg(priv, 0x04, lpf_mxdiv); | 221 | ret = regmap_write(dev->regmap, 0x04, lpf_mxdiv); |
331 | if (ret) | 222 | if (ret) |
332 | goto err; | 223 | goto err; |
333 | 224 | ||
334 | ret = m88ts2022_wr_reg(priv, 0x06, lpf_gm); | 225 | ret = regmap_write(dev->regmap, 0x06, lpf_gm); |
335 | if (ret) | 226 | if (ret) |
336 | goto err; | 227 | goto err; |
337 | 228 | ||
338 | ret = m88ts2022_cmd(fe, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); | 229 | ret = m88ts2022_cmd(dev, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); |
339 | if (ret) | 230 | if (ret) |
340 | goto err; | 231 | goto err; |
341 | 232 | ||
342 | cap_code = u8tmp & 0x3f; | 233 | cap_code = u8tmp & 0x3f; |
343 | 234 | ||
344 | ret = m88ts2022_wr_reg(priv, 0x41, 0x09); | 235 | ret = regmap_write(dev->regmap, 0x41, 0x09); |
345 | if (ret) | 236 | if (ret) |
346 | goto err; | 237 | goto err; |
347 | 238 | ||
348 | ret = m88ts2022_cmd(fe, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); | 239 | ret = m88ts2022_cmd(dev, 0x04, 2, 0x26, 0xff, 0x00, &u8tmp); |
349 | if (ret) | 240 | if (ret) |
350 | goto err; | 241 | goto err; |
351 | 242 | ||
@@ -353,31 +244,31 @@ static int m88ts2022_set_params(struct dvb_frontend *fe) | |||
353 | cap_code = (cap_code + u8tmp) / 2; | 244 | cap_code = (cap_code + u8tmp) / 2; |
354 | 245 | ||
355 | u8tmp = cap_code | 0x80; | 246 | u8tmp = cap_code | 0x80; |
356 | ret = m88ts2022_wr_reg(priv, 0x25, u8tmp); | 247 | ret = regmap_write(dev->regmap, 0x25, u8tmp); |
357 | if (ret) | 248 | if (ret) |
358 | goto err; | 249 | goto err; |
359 | 250 | ||
360 | ret = m88ts2022_wr_reg(priv, 0x27, 0x30); | 251 | ret = regmap_write(dev->regmap, 0x27, 0x30); |
361 | if (ret) | 252 | if (ret) |
362 | goto err; | 253 | goto err; |
363 | 254 | ||
364 | ret = m88ts2022_wr_reg(priv, 0x08, 0x09); | 255 | ret = regmap_write(dev->regmap, 0x08, 0x09); |
365 | if (ret) | 256 | if (ret) |
366 | goto err; | 257 | goto err; |
367 | 258 | ||
368 | ret = m88ts2022_cmd(fe, 0x01, 20, 0x21, 0xff, 0x00, NULL); | 259 | ret = m88ts2022_cmd(dev, 0x01, 20, 0x21, 0xff, 0x00, NULL); |
369 | if (ret) | 260 | if (ret) |
370 | goto err; | 261 | goto err; |
371 | err: | 262 | err: |
372 | if (ret) | 263 | if (ret) |
373 | dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret); | 264 | dev_dbg(&dev->client->dev, "failed=%d\n", ret); |
374 | 265 | ||
375 | return ret; | 266 | return ret; |
376 | } | 267 | } |
377 | 268 | ||
378 | static int m88ts2022_init(struct dvb_frontend *fe) | 269 | static int m88ts2022_init(struct dvb_frontend *fe) |
379 | { | 270 | { |
380 | struct m88ts2022_priv *priv = fe->tuner_priv; | 271 | struct m88ts2022_dev *dev = fe->tuner_priv; |
381 | int ret, i; | 272 | int ret, i; |
382 | u8 u8tmp; | 273 | u8 u8tmp; |
383 | static const struct m88ts2022_reg_val reg_vals[] = { | 274 | static const struct m88ts2022_reg_val reg_vals[] = { |
@@ -393,23 +284,24 @@ static int m88ts2022_init(struct dvb_frontend *fe) | |||
393 | {0x24, 0x02}, | 284 | {0x24, 0x02}, |
394 | {0x12, 0xa0}, | 285 | {0x12, 0xa0}, |
395 | }; | 286 | }; |
396 | dev_dbg(&priv->client->dev, "%s:\n", __func__); | ||
397 | 287 | ||
398 | ret = m88ts2022_wr_reg(priv, 0x00, 0x01); | 288 | dev_dbg(&dev->client->dev, "\n"); |
289 | |||
290 | ret = regmap_write(dev->regmap, 0x00, 0x01); | ||
399 | if (ret) | 291 | if (ret) |
400 | goto err; | 292 | goto err; |
401 | 293 | ||
402 | ret = m88ts2022_wr_reg(priv, 0x00, 0x03); | 294 | ret = regmap_write(dev->regmap, 0x00, 0x03); |
403 | if (ret) | 295 | if (ret) |
404 | goto err; | 296 | goto err; |
405 | 297 | ||
406 | switch (priv->cfg.clock_out) { | 298 | switch (dev->cfg.clock_out) { |
407 | case M88TS2022_CLOCK_OUT_DISABLED: | 299 | case M88TS2022_CLOCK_OUT_DISABLED: |
408 | u8tmp = 0x60; | 300 | u8tmp = 0x60; |
409 | break; | 301 | break; |
410 | case M88TS2022_CLOCK_OUT_ENABLED: | 302 | case M88TS2022_CLOCK_OUT_ENABLED: |
411 | u8tmp = 0x70; | 303 | u8tmp = 0x70; |
412 | ret = m88ts2022_wr_reg(priv, 0x05, priv->cfg.clock_out_div); | 304 | ret = regmap_write(dev->regmap, 0x05, dev->cfg.clock_out_div); |
413 | if (ret) | 305 | if (ret) |
414 | goto err; | 306 | goto err; |
415 | break; | 307 | break; |
@@ -420,58 +312,61 @@ static int m88ts2022_init(struct dvb_frontend *fe) | |||
420 | goto err; | 312 | goto err; |
421 | } | 313 | } |
422 | 314 | ||
423 | ret = m88ts2022_wr_reg(priv, 0x42, u8tmp); | 315 | ret = regmap_write(dev->regmap, 0x42, u8tmp); |
424 | if (ret) | 316 | if (ret) |
425 | goto err; | 317 | goto err; |
426 | 318 | ||
427 | if (priv->cfg.loop_through) | 319 | if (dev->cfg.loop_through) |
428 | u8tmp = 0xec; | 320 | u8tmp = 0xec; |
429 | else | 321 | else |
430 | u8tmp = 0x6c; | 322 | u8tmp = 0x6c; |
431 | 323 | ||
432 | ret = m88ts2022_wr_reg(priv, 0x62, u8tmp); | 324 | ret = regmap_write(dev->regmap, 0x62, u8tmp); |
433 | if (ret) | 325 | if (ret) |
434 | goto err; | 326 | goto err; |
435 | 327 | ||
436 | for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { | 328 | for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { |
437 | ret = m88ts2022_wr_reg(priv, reg_vals[i].reg, reg_vals[i].val); | 329 | ret = regmap_write(dev->regmap, reg_vals[i].reg, reg_vals[i].val); |
438 | if (ret) | 330 | if (ret) |
439 | goto err; | 331 | goto err; |
440 | } | 332 | } |
441 | err: | 333 | err: |
442 | if (ret) | 334 | if (ret) |
443 | dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret); | 335 | dev_dbg(&dev->client->dev, "failed=%d\n", ret); |
444 | return ret; | 336 | return ret; |
445 | } | 337 | } |
446 | 338 | ||
447 | static int m88ts2022_sleep(struct dvb_frontend *fe) | 339 | static int m88ts2022_sleep(struct dvb_frontend *fe) |
448 | { | 340 | { |
449 | struct m88ts2022_priv *priv = fe->tuner_priv; | 341 | struct m88ts2022_dev *dev = fe->tuner_priv; |
450 | int ret; | 342 | int ret; |
451 | dev_dbg(&priv->client->dev, "%s:\n", __func__); | ||
452 | 343 | ||
453 | ret = m88ts2022_wr_reg(priv, 0x00, 0x00); | 344 | dev_dbg(&dev->client->dev, "\n"); |
345 | |||
346 | ret = regmap_write(dev->regmap, 0x00, 0x00); | ||
454 | if (ret) | 347 | if (ret) |
455 | goto err; | 348 | goto err; |
456 | err: | 349 | err: |
457 | if (ret) | 350 | if (ret) |
458 | dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret); | 351 | dev_dbg(&dev->client->dev, "failed=%d\n", ret); |
459 | return ret; | 352 | return ret; |
460 | } | 353 | } |
461 | 354 | ||
462 | static int m88ts2022_get_frequency(struct dvb_frontend *fe, u32 *frequency) | 355 | static int m88ts2022_get_frequency(struct dvb_frontend *fe, u32 *frequency) |
463 | { | 356 | { |
464 | struct m88ts2022_priv *priv = fe->tuner_priv; | 357 | struct m88ts2022_dev *dev = fe->tuner_priv; |
465 | dev_dbg(&priv->client->dev, "%s:\n", __func__); | ||
466 | 358 | ||
467 | *frequency = priv->frequency_khz; | 359 | dev_dbg(&dev->client->dev, "\n"); |
360 | |||
361 | *frequency = dev->frequency_khz; | ||
468 | return 0; | 362 | return 0; |
469 | } | 363 | } |
470 | 364 | ||
471 | static int m88ts2022_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | 365 | static int m88ts2022_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) |
472 | { | 366 | { |
473 | struct m88ts2022_priv *priv = fe->tuner_priv; | 367 | struct m88ts2022_dev *dev = fe->tuner_priv; |
474 | dev_dbg(&priv->client->dev, "%s:\n", __func__); | 368 | |
369 | dev_dbg(&dev->client->dev, "\n"); | ||
475 | 370 | ||
476 | *frequency = 0; /* Zero-IF */ | 371 | *frequency = 0; /* Zero-IF */ |
477 | return 0; | 372 | return 0; |
@@ -479,31 +374,30 @@ static int m88ts2022_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
479 | 374 | ||
480 | static int m88ts2022_get_rf_strength(struct dvb_frontend *fe, u16 *strength) | 375 | static int m88ts2022_get_rf_strength(struct dvb_frontend *fe, u16 *strength) |
481 | { | 376 | { |
482 | struct m88ts2022_priv *priv = fe->tuner_priv; | 377 | struct m88ts2022_dev *dev = fe->tuner_priv; |
483 | int ret; | 378 | int ret; |
484 | u8 u8tmp; | ||
485 | u16 gain, u16tmp; | 379 | u16 gain, u16tmp; |
486 | unsigned int gain1, gain2, gain3; | 380 | unsigned int utmp, gain1, gain2, gain3; |
487 | 381 | ||
488 | ret = m88ts2022_rd_reg(priv, 0x3d, &u8tmp); | 382 | ret = regmap_read(dev->regmap, 0x3d, &utmp); |
489 | if (ret) | 383 | if (ret) |
490 | goto err; | 384 | goto err; |
491 | 385 | ||
492 | gain1 = (u8tmp >> 0) & 0x1f; | 386 | gain1 = (utmp >> 0) & 0x1f; |
493 | gain1 = clamp(gain1, 0U, 15U); | 387 | gain1 = clamp(gain1, 0U, 15U); |
494 | 388 | ||
495 | ret = m88ts2022_rd_reg(priv, 0x21, &u8tmp); | 389 | ret = regmap_read(dev->regmap, 0x21, &utmp); |
496 | if (ret) | 390 | if (ret) |
497 | goto err; | 391 | goto err; |
498 | 392 | ||
499 | gain2 = (u8tmp >> 0) & 0x1f; | 393 | gain2 = (utmp >> 0) & 0x1f; |
500 | gain2 = clamp(gain2, 2U, 16U); | 394 | gain2 = clamp(gain2, 2U, 16U); |
501 | 395 | ||
502 | ret = m88ts2022_rd_reg(priv, 0x66, &u8tmp); | 396 | ret = regmap_read(dev->regmap, 0x66, &utmp); |
503 | if (ret) | 397 | if (ret) |
504 | goto err; | 398 | goto err; |
505 | 399 | ||
506 | gain3 = (u8tmp >> 3) & 0x07; | 400 | gain3 = (utmp >> 3) & 0x07; |
507 | gain3 = clamp(gain3, 0U, 6U); | 401 | gain3 = clamp(gain3, 0U, 6U); |
508 | 402 | ||
509 | gain = gain1 * 265 + gain2 * 338 + gain3 * 285; | 403 | gain = gain1 * 265 + gain2 * 338 + gain3 * 285; |
@@ -515,7 +409,7 @@ static int m88ts2022_get_rf_strength(struct dvb_frontend *fe, u16 *strength) | |||
515 | *strength = (u16tmp - 59000) * 0xffff / (61500 - 59000); | 409 | *strength = (u16tmp - 59000) * 0xffff / (61500 - 59000); |
516 | err: | 410 | err: |
517 | if (ret) | 411 | if (ret) |
518 | dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret); | 412 | dev_dbg(&dev->client->dev, "failed=%d\n", ret); |
519 | return ret; | 413 | return ret; |
520 | } | 414 | } |
521 | 415 | ||
@@ -540,46 +434,56 @@ static int m88ts2022_probe(struct i2c_client *client, | |||
540 | { | 434 | { |
541 | struct m88ts2022_config *cfg = client->dev.platform_data; | 435 | struct m88ts2022_config *cfg = client->dev.platform_data; |
542 | struct dvb_frontend *fe = cfg->fe; | 436 | struct dvb_frontend *fe = cfg->fe; |
543 | struct m88ts2022_priv *priv; | 437 | struct m88ts2022_dev *dev; |
544 | int ret; | 438 | int ret; |
545 | u8 chip_id, u8tmp; | 439 | u8 u8tmp; |
440 | unsigned int utmp; | ||
441 | static const struct regmap_config regmap_config = { | ||
442 | .reg_bits = 8, | ||
443 | .val_bits = 8, | ||
444 | }; | ||
546 | 445 | ||
547 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 446 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
548 | if (!priv) { | 447 | if (!dev) { |
549 | ret = -ENOMEM; | 448 | ret = -ENOMEM; |
550 | dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); | 449 | dev_err(&client->dev, "kzalloc() failed\n"); |
551 | goto err; | 450 | goto err; |
552 | } | 451 | } |
553 | 452 | ||
554 | memcpy(&priv->cfg, cfg, sizeof(struct m88ts2022_config)); | 453 | memcpy(&dev->cfg, cfg, sizeof(struct m88ts2022_config)); |
555 | priv->client = client; | 454 | dev->client = client; |
455 | dev->regmap = devm_regmap_init_i2c(client, ®map_config); | ||
456 | if (IS_ERR(dev->regmap)) { | ||
457 | ret = PTR_ERR(dev->regmap); | ||
458 | goto err; | ||
459 | } | ||
556 | 460 | ||
557 | /* check if the tuner is there */ | 461 | /* check if the tuner is there */ |
558 | ret = m88ts2022_rd_reg(priv, 0x00, &u8tmp); | 462 | ret = regmap_read(dev->regmap, 0x00, &utmp); |
559 | if (ret) | 463 | if (ret) |
560 | goto err; | 464 | goto err; |
561 | 465 | ||
562 | if ((u8tmp & 0x03) == 0x00) { | 466 | if ((utmp & 0x03) == 0x00) { |
563 | ret = m88ts2022_wr_reg(priv, 0x00, 0x01); | 467 | ret = regmap_write(dev->regmap, 0x00, 0x01); |
564 | if (ret < 0) | 468 | if (ret) |
565 | goto err; | 469 | goto err; |
566 | 470 | ||
567 | usleep_range(2000, 50000); | 471 | usleep_range(2000, 50000); |
568 | } | 472 | } |
569 | 473 | ||
570 | ret = m88ts2022_wr_reg(priv, 0x00, 0x03); | 474 | ret = regmap_write(dev->regmap, 0x00, 0x03); |
571 | if (ret) | 475 | if (ret) |
572 | goto err; | 476 | goto err; |
573 | 477 | ||
574 | usleep_range(2000, 50000); | 478 | usleep_range(2000, 50000); |
575 | 479 | ||
576 | ret = m88ts2022_rd_reg(priv, 0x00, &chip_id); | 480 | ret = regmap_read(dev->regmap, 0x00, &utmp); |
577 | if (ret) | 481 | if (ret) |
578 | goto err; | 482 | goto err; |
579 | 483 | ||
580 | dev_dbg(&priv->client->dev, "%s: chip_id=%02x\n", __func__, chip_id); | 484 | dev_dbg(&dev->client->dev, "chip_id=%02x\n", utmp); |
581 | 485 | ||
582 | switch (chip_id) { | 486 | switch (utmp) { |
583 | case 0xc3: | 487 | case 0xc3: |
584 | case 0x83: | 488 | case 0x83: |
585 | break; | 489 | break; |
@@ -587,13 +491,13 @@ static int m88ts2022_probe(struct i2c_client *client, | |||
587 | goto err; | 491 | goto err; |
588 | } | 492 | } |
589 | 493 | ||
590 | switch (priv->cfg.clock_out) { | 494 | switch (dev->cfg.clock_out) { |
591 | case M88TS2022_CLOCK_OUT_DISABLED: | 495 | case M88TS2022_CLOCK_OUT_DISABLED: |
592 | u8tmp = 0x60; | 496 | u8tmp = 0x60; |
593 | break; | 497 | break; |
594 | case M88TS2022_CLOCK_OUT_ENABLED: | 498 | case M88TS2022_CLOCK_OUT_ENABLED: |
595 | u8tmp = 0x70; | 499 | u8tmp = 0x70; |
596 | ret = m88ts2022_wr_reg(priv, 0x05, priv->cfg.clock_out_div); | 500 | ret = regmap_write(dev->regmap, 0x05, dev->cfg.clock_out_div); |
597 | if (ret) | 501 | if (ret) |
598 | goto err; | 502 | goto err; |
599 | break; | 503 | break; |
@@ -604,49 +508,48 @@ static int m88ts2022_probe(struct i2c_client *client, | |||
604 | goto err; | 508 | goto err; |
605 | } | 509 | } |
606 | 510 | ||
607 | ret = m88ts2022_wr_reg(priv, 0x42, u8tmp); | 511 | ret = regmap_write(dev->regmap, 0x42, u8tmp); |
608 | if (ret) | 512 | if (ret) |
609 | goto err; | 513 | goto err; |
610 | 514 | ||
611 | if (priv->cfg.loop_through) | 515 | if (dev->cfg.loop_through) |
612 | u8tmp = 0xec; | 516 | u8tmp = 0xec; |
613 | else | 517 | else |
614 | u8tmp = 0x6c; | 518 | u8tmp = 0x6c; |
615 | 519 | ||
616 | ret = m88ts2022_wr_reg(priv, 0x62, u8tmp); | 520 | ret = regmap_write(dev->regmap, 0x62, u8tmp); |
617 | if (ret) | 521 | if (ret) |
618 | goto err; | 522 | goto err; |
619 | 523 | ||
620 | /* sleep */ | 524 | /* sleep */ |
621 | ret = m88ts2022_wr_reg(priv, 0x00, 0x00); | 525 | ret = regmap_write(dev->regmap, 0x00, 0x00); |
622 | if (ret) | 526 | if (ret) |
623 | goto err; | 527 | goto err; |
624 | 528 | ||
625 | dev_info(&priv->client->dev, | 529 | dev_info(&dev->client->dev, "Montage M88TS2022 successfully identified\n"); |
626 | "%s: Montage M88TS2022 successfully identified\n", | ||
627 | KBUILD_MODNAME); | ||
628 | 530 | ||
629 | fe->tuner_priv = priv; | 531 | fe->tuner_priv = dev; |
630 | memcpy(&fe->ops.tuner_ops, &m88ts2022_tuner_ops, | 532 | memcpy(&fe->ops.tuner_ops, &m88ts2022_tuner_ops, |
631 | sizeof(struct dvb_tuner_ops)); | 533 | sizeof(struct dvb_tuner_ops)); |
632 | 534 | ||
633 | i2c_set_clientdata(client, priv); | 535 | i2c_set_clientdata(client, dev); |
634 | return 0; | 536 | return 0; |
635 | err: | 537 | err: |
636 | dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret); | 538 | dev_dbg(&client->dev, "failed=%d\n", ret); |
637 | kfree(priv); | 539 | kfree(dev); |
638 | return ret; | 540 | return ret; |
639 | } | 541 | } |
640 | 542 | ||
641 | static int m88ts2022_remove(struct i2c_client *client) | 543 | static int m88ts2022_remove(struct i2c_client *client) |
642 | { | 544 | { |
643 | struct m88ts2022_priv *priv = i2c_get_clientdata(client); | 545 | struct m88ts2022_dev *dev = i2c_get_clientdata(client); |
644 | struct dvb_frontend *fe = priv->cfg.fe; | 546 | struct dvb_frontend *fe = dev->cfg.fe; |
645 | dev_dbg(&client->dev, "%s:\n", __func__); | 547 | |
548 | dev_dbg(&client->dev, "\n"); | ||
646 | 549 | ||
647 | memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); | 550 | memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); |
648 | fe->tuner_priv = NULL; | 551 | fe->tuner_priv = NULL; |
649 | kfree(priv); | 552 | kfree(dev); |
650 | 553 | ||
651 | return 0; | 554 | return 0; |
652 | } | 555 | } |