Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[linux-2.6.git] / drivers / media / dvb / frontends / stb6000.c
1   /*
2      Driver for ST STB6000 DVBS Silicon tuner
3
4      Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
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
15      GNU General Public License for more details.
16
17      You should have received a copy of the GNU General Public License
18      along with this program; if not, write to the Free Software
19      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21   */
22
23 #include <linux/slab.h>
24 #include <linux/module.h>
25 #include <linux/dvb/frontend.h>
26 #include <asm/types.h>
27
28 #include "stb6000.h"
29
30 static int debug;
31 #define dprintk(args...) \
32         do { \
33                 if (debug) \
34                         printk(KERN_DEBUG "stb6000: " args); \
35         } while (0)
36
37 struct stb6000_priv {
38         /* i2c details */
39         int i2c_address;
40         struct i2c_adapter *i2c;
41         u32 frequency;
42 };
43
44 static int stb6000_release(struct dvb_frontend *fe)
45 {
46         kfree(fe->tuner_priv);
47         fe->tuner_priv = NULL;
48         return 0;
49 }
50
51 static int stb6000_sleep(struct dvb_frontend *fe)
52 {
53         struct stb6000_priv *priv = fe->tuner_priv;
54         int ret;
55         u8 buf[] = { 10, 0 };
56         struct i2c_msg msg = {
57                 .addr = priv->i2c_address,
58                 .flags = 0,
59                 .buf = buf,
60                 .len = 2
61         };
62
63         dprintk("%s:\n", __func__);
64
65         if (fe->ops.i2c_gate_ctrl)
66                 fe->ops.i2c_gate_ctrl(fe, 1);
67
68         ret = i2c_transfer(priv->i2c, &msg, 1);
69         if (ret != 1)
70                 dprintk("%s: i2c error\n", __func__);
71
72         if (fe->ops.i2c_gate_ctrl)
73                 fe->ops.i2c_gate_ctrl(fe, 0);
74
75         return (ret == 1) ? 0 : ret;
76 }
77
78 static int stb6000_set_params(struct dvb_frontend *fe)
79 {
80         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
81         struct stb6000_priv *priv = fe->tuner_priv;
82         unsigned int n, m;
83         int ret;
84         u32 freq_mhz;
85         int bandwidth;
86         u8 buf[12];
87         struct i2c_msg msg = {
88                 .addr = priv->i2c_address,
89                 .flags = 0,
90                 .buf = buf,
91                 .len = 12
92         };
93
94         dprintk("%s:\n", __func__);
95
96         freq_mhz = p->frequency / 1000;
97         bandwidth = p->symbol_rate / 1000000;
98
99         if (bandwidth > 31)
100                 bandwidth = 31;
101
102         if ((freq_mhz > 949) && (freq_mhz < 2151)) {
103                 buf[0] = 0x01;
104                 buf[1] = 0xac;
105                 if (freq_mhz < 1950)
106                         buf[1] = 0xaa;
107                 if (freq_mhz < 1800)
108                         buf[1] = 0xa8;
109                 if (freq_mhz < 1650)
110                         buf[1] = 0xa6;
111                 if (freq_mhz < 1530)
112                         buf[1] = 0xa5;
113                 if (freq_mhz < 1470)
114                         buf[1] = 0xa4;
115                 if (freq_mhz < 1370)
116                         buf[1] = 0xa2;
117                 if (freq_mhz < 1300)
118                         buf[1] = 0xa1;
119                 if (freq_mhz < 1200)
120                         buf[1] = 0xa0;
121                 if (freq_mhz < 1075)
122                         buf[1] = 0xbc;
123                 if (freq_mhz < 1000)
124                         buf[1] = 0xba;
125                 if (freq_mhz < 1075) {
126                         n = freq_mhz / 8; /* vco=lo*4 */
127                         m = 2;
128                 } else {
129                         n = freq_mhz / 16; /* vco=lo*2 */
130                         m = 1;
131                 }
132                 buf[2] = n >> 1;
133                 buf[3] = (unsigned char)(((n & 1) << 7) |
134                                         (m * freq_mhz - n * 16) | 0x60);
135                 buf[4] = 0x04;
136                 buf[5] = 0x0e;
137
138                 buf[6] = (unsigned char)(bandwidth);
139
140                 buf[7] = 0xd8;
141                 buf[8] = 0xd0;
142                 buf[9] = 0x50;
143                 buf[10] = 0xeb;
144                 buf[11] = 0x4f;
145
146                 if (fe->ops.i2c_gate_ctrl)
147                         fe->ops.i2c_gate_ctrl(fe, 1);
148
149                 ret = i2c_transfer(priv->i2c, &msg, 1);
150                 if (ret != 1)
151                         dprintk("%s: i2c error\n", __func__);
152
153                 udelay(10);
154                 if (fe->ops.i2c_gate_ctrl)
155                         fe->ops.i2c_gate_ctrl(fe, 0);
156
157                 buf[0] = 0x07;
158                 buf[1] = 0xdf;
159                 buf[2] = 0xd0;
160                 buf[3] = 0x50;
161                 buf[4] = 0xfb;
162                 msg.len = 5;
163
164                 if (fe->ops.i2c_gate_ctrl)
165                         fe->ops.i2c_gate_ctrl(fe, 1);
166
167                 ret = i2c_transfer(priv->i2c, &msg, 1);
168                 if (ret != 1)
169                         dprintk("%s: i2c error\n", __func__);
170
171                 udelay(10);
172                 if (fe->ops.i2c_gate_ctrl)
173                         fe->ops.i2c_gate_ctrl(fe, 0);
174
175                 priv->frequency = freq_mhz * 1000;
176
177                 return (ret == 1) ? 0 : ret;
178         }
179         return -1;
180 }
181
182 static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
183 {
184         struct stb6000_priv *priv = fe->tuner_priv;
185         *frequency = priv->frequency;
186         return 0;
187 }
188
189 static struct dvb_tuner_ops stb6000_tuner_ops = {
190         .info = {
191                 .name = "ST STB6000",
192                 .frequency_min = 950000,
193                 .frequency_max = 2150000
194         },
195         .release = stb6000_release,
196         .sleep = stb6000_sleep,
197         .set_params = stb6000_set_params,
198         .get_frequency = stb6000_get_frequency,
199 };
200
201 struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
202                                                 struct i2c_adapter *i2c)
203 {
204         struct stb6000_priv *priv = NULL;
205         u8 b0[] = { 0 };
206         u8 b1[] = { 0, 0 };
207         struct i2c_msg msg[2] = {
208                 {
209                         .addr = addr,
210                         .flags = 0,
211                         .buf = b0,
212                         .len = 0
213                 }, {
214                         .addr = addr,
215                         .flags = I2C_M_RD,
216                         .buf = b1,
217                         .len = 2
218                 }
219         };
220         int ret;
221
222         dprintk("%s:\n", __func__);
223
224         if (fe->ops.i2c_gate_ctrl)
225                 fe->ops.i2c_gate_ctrl(fe, 1);
226
227         /* is some i2c device here ? */
228         ret = i2c_transfer(i2c, msg, 2);
229         if (fe->ops.i2c_gate_ctrl)
230                 fe->ops.i2c_gate_ctrl(fe, 0);
231
232         if (ret != 2)
233                 return NULL;
234
235         priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
236         if (priv == NULL)
237                 return NULL;
238
239         priv->i2c_address = addr;
240         priv->i2c = i2c;
241
242         memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
243                                 sizeof(struct dvb_tuner_ops));
244
245         fe->tuner_priv = priv;
246
247         return fe;
248 }
249 EXPORT_SYMBOL(stb6000_attach);
250
251 module_param(debug, int, 0644);
252 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
253
254 MODULE_DESCRIPTION("DVB STB6000 driver");
255 MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
256 MODULE_LICENSE("GPL");