GNU Linux-libre 4.14.290-gnu1
[releases.git] / drivers / media / tuners / tda18218.c
1 /*
2  * NXP TDA18218HN silicon tuner driver
3  *
4  * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
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
17 #include "tda18218_priv.h"
18
19 /* Max transfer size done by I2C transfer functions */
20 #define MAX_XFER_SIZE  64
21
22 /* write multiple registers */
23 static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
24 {
25         int ret = 0, len2, remaining;
26         u8 buf[MAX_XFER_SIZE];
27         struct i2c_msg msg[1] = {
28                 {
29                         .addr = priv->cfg->i2c_address,
30                         .flags = 0,
31                         .buf = buf,
32                 }
33         };
34
35         if (1 + len > sizeof(buf)) {
36                 dev_warn(&priv->i2c->dev,
37                          "%s: i2c wr reg=%04x: len=%d is too big!\n",
38                          KBUILD_MODNAME, reg, len);
39                 return -EINVAL;
40         }
41
42         for (remaining = len; remaining > 0;
43                         remaining -= (priv->cfg->i2c_wr_max - 1)) {
44                 len2 = remaining;
45                 if (len2 > (priv->cfg->i2c_wr_max - 1))
46                         len2 = (priv->cfg->i2c_wr_max - 1);
47
48                 msg[0].len = 1 + len2;
49                 buf[0] = reg + len - remaining;
50                 memcpy(&buf[1], &val[len - remaining], len2);
51
52                 ret = i2c_transfer(priv->i2c, msg, 1);
53                 if (ret != 1)
54                         break;
55         }
56
57         if (ret == 1) {
58                 ret = 0;
59         } else {
60                 dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
61                                 "len=%d\n", KBUILD_MODNAME, ret, reg, len);
62                 ret = -EREMOTEIO;
63         }
64
65         return ret;
66 }
67
68 /* read multiple registers */
69 static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
70 {
71         int ret;
72         u8 buf[MAX_XFER_SIZE]; /* we must start read always from reg 0x00 */
73         struct i2c_msg msg[2] = {
74                 {
75                         .addr = priv->cfg->i2c_address,
76                         .flags = 0,
77                         .len = 1,
78                         .buf = "\x00",
79                 }, {
80                         .addr = priv->cfg->i2c_address,
81                         .flags = I2C_M_RD,
82                         .len = reg + len,
83                         .buf = buf,
84                 }
85         };
86
87         if (reg + len > sizeof(buf)) {
88                 dev_warn(&priv->i2c->dev,
89                          "%s: i2c wr reg=%04x: len=%d is too big!\n",
90                          KBUILD_MODNAME, reg, len);
91                 return -EINVAL;
92         }
93
94         ret = i2c_transfer(priv->i2c, msg, 2);
95         if (ret == 2) {
96                 memcpy(val, &buf[reg], len);
97                 ret = 0;
98         } else {
99                 dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
100                                 "len=%d\n", KBUILD_MODNAME, ret, reg, len);
101                 ret = -EREMOTEIO;
102         }
103
104         return ret;
105 }
106
107 /* write single register */
108 static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val)
109 {
110         return tda18218_wr_regs(priv, reg, &val, 1);
111 }
112
113 /* read single register */
114
115 static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val)
116 {
117         return tda18218_rd_regs(priv, reg, val, 1);
118 }
119
120 static int tda18218_set_params(struct dvb_frontend *fe)
121 {
122         struct tda18218_priv *priv = fe->tuner_priv;
123         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
124         u32 bw = c->bandwidth_hz;
125         int ret;
126         u8 buf[3], i, BP_Filter, LP_Fc;
127         u32 LO_Frac;
128         /* TODO: find out correct AGC algorithm */
129         u8 agc[][2] = {
130                 { R20_AGC11, 0x60 },
131                 { R23_AGC21, 0x02 },
132                 { R20_AGC11, 0xa0 },
133                 { R23_AGC21, 0x09 },
134                 { R20_AGC11, 0xe0 },
135                 { R23_AGC21, 0x0c },
136                 { R20_AGC11, 0x40 },
137                 { R23_AGC21, 0x01 },
138                 { R20_AGC11, 0x80 },
139                 { R23_AGC21, 0x08 },
140                 { R20_AGC11, 0xc0 },
141                 { R23_AGC21, 0x0b },
142                 { R24_AGC22, 0x1c },
143                 { R24_AGC22, 0x0c },
144         };
145
146         if (fe->ops.i2c_gate_ctrl)
147                 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
148
149         /* low-pass filter cut-off frequency */
150         if (bw <= 6000000) {
151                 LP_Fc = 0;
152                 priv->if_frequency = 3000000;
153         } else if (bw <= 7000000) {
154                 LP_Fc = 1;
155                 priv->if_frequency = 3500000;
156         } else {
157                 LP_Fc = 2;
158                 priv->if_frequency = 4000000;
159         }
160
161         LO_Frac = c->frequency + priv->if_frequency;
162
163         /* band-pass filter */
164         if (LO_Frac < 188000000)
165                 BP_Filter = 3;
166         else if (LO_Frac < 253000000)
167                 BP_Filter = 4;
168         else if (LO_Frac < 343000000)
169                 BP_Filter = 5;
170         else
171                 BP_Filter = 6;
172
173         buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */
174         buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */
175         buf[2] = priv->regs[R1C_AGC2B];
176         ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3);
177         if (ret)
178                 goto error;
179
180         buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */
181         buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */
182         buf[2] = (LO_Frac / 1000) << 4 |
183                 (priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */
184         ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3);
185         if (ret)
186                 goto error;
187
188         buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */
189         ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
190         if (ret)
191                 goto error;
192
193         buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */
194         ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
195         if (ret)
196                 goto error;
197
198         /* trigger AGC */
199         for (i = 0; i < ARRAY_SIZE(agc); i++) {
200                 ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]);
201                 if (ret)
202                         goto error;
203         }
204
205 error:
206         if (fe->ops.i2c_gate_ctrl)
207                 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
208
209         if (ret)
210                 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
211
212         return ret;
213 }
214
215 static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
216 {
217         struct tda18218_priv *priv = fe->tuner_priv;
218         *frequency = priv->if_frequency;
219         dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d\n", __func__, *frequency);
220         return 0;
221 }
222
223 static int tda18218_sleep(struct dvb_frontend *fe)
224 {
225         struct tda18218_priv *priv = fe->tuner_priv;
226         int ret;
227
228         if (fe->ops.i2c_gate_ctrl)
229                 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
230
231         /* standby */
232         ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
233
234         if (fe->ops.i2c_gate_ctrl)
235                 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
236
237         if (ret)
238                 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
239
240         return ret;
241 }
242
243 static int tda18218_init(struct dvb_frontend *fe)
244 {
245         struct tda18218_priv *priv = fe->tuner_priv;
246         int ret;
247
248         /* TODO: calibrations */
249
250         if (fe->ops.i2c_gate_ctrl)
251                 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
252
253         ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS);
254
255         if (fe->ops.i2c_gate_ctrl)
256                 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
257
258         if (ret)
259                 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
260
261         return ret;
262 }
263
264 static void tda18218_release(struct dvb_frontend *fe)
265 {
266         kfree(fe->tuner_priv);
267         fe->tuner_priv = NULL;
268 }
269
270 static const struct dvb_tuner_ops tda18218_tuner_ops = {
271         .info = {
272                 .name           = "NXP TDA18218",
273
274                 .frequency_min  = 174000000,
275                 .frequency_max  = 864000000,
276                 .frequency_step =      1000,
277         },
278
279         .release       = tda18218_release,
280         .init          = tda18218_init,
281         .sleep         = tda18218_sleep,
282
283         .set_params    = tda18218_set_params,
284
285         .get_if_frequency = tda18218_get_if_frequency,
286 };
287
288 struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
289         struct i2c_adapter *i2c, struct tda18218_config *cfg)
290 {
291         struct tda18218_priv *priv = NULL;
292         u8 val;
293         int ret;
294         /* chip default registers values */
295         static u8 def_regs[] = {
296                 0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40,
297                 0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00,
298                 0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01,
299                 0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9,
300                 0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00,
301                 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6
302         };
303
304         priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
305         if (priv == NULL)
306                 return NULL;
307
308         priv->cfg = cfg;
309         priv->i2c = i2c;
310         fe->tuner_priv = priv;
311
312         if (fe->ops.i2c_gate_ctrl)
313                 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
314
315         /* check if the tuner is there */
316         ret = tda18218_rd_reg(priv, R00_ID, &val);
317         if (!ret)
318                 dev_dbg(&priv->i2c->dev, "%s: chip id=%02x\n", __func__, val);
319         if (ret || val != def_regs[R00_ID]) {
320                 kfree(priv);
321                 return NULL;
322         }
323
324         dev_info(&priv->i2c->dev,
325                         "%s: NXP TDA18218HN successfully identified\n",
326                         KBUILD_MODNAME);
327
328         memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
329                 sizeof(struct dvb_tuner_ops));
330         memcpy(priv->regs, def_regs, sizeof(def_regs));
331
332         /* loop-through enabled chip default register values */
333         if (priv->cfg->loop_through) {
334                 priv->regs[R17_PD1] = 0xb0;
335                 priv->regs[R18_PD2] = 0x59;
336         }
337
338         /* standby */
339         ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
340         if (ret)
341                 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
342
343         if (fe->ops.i2c_gate_ctrl)
344                 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
345
346         return fe;
347 }
348 EXPORT_SYMBOL(tda18218_attach);
349
350 MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
351 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
352 MODULE_LICENSE("GPL");