blob: ebd1ee9dc871d222f6f918b8670aa407037e9777 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002
3 bttv-i2c.c -- all the i2c code is here
4
5 bttv - Bt848 frame grabber driver
6
7 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -08008 & Marcus Metzler (mocm@thp.uni-koeln.de)
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
10
Mauro Carvalho Chehab141276b2006-09-06 19:04:28 -030011 (c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
12 - Multituner support and i2c address binding
13
Linus Torvalds1da177e2005-04-16 15:20:36 -070014 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28*/
29
30#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <linux/init.h>
32#include <linux/delay.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033
34#include "bttvp.h"
Michael Krufky5e453dc2006-01-09 15:32:31 -020035#include <media/v4l2-common.h>
Mauro Carvalho Chehabb5b8ab82006-01-09 15:25:20 -020036#include <linux/jiffies.h>
37#include <asm/io.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
Mauro Carvalho Chehaba5ed4252006-01-13 14:10:19 -020039static int i2c_debug;
40static int i2c_hw;
41static int i2c_scan;
Linus Torvalds1da177e2005-04-16 15:20:36 -070042module_param(i2c_debug, int, 0644);
Mauro Carvalho Chehab141276b2006-09-06 19:04:28 -030043MODULE_PARM_DESC(i2c_hw,"configure i2c debug level");
Linus Torvalds1da177e2005-04-16 15:20:36 -070044module_param(i2c_hw, int, 0444);
Mauro Carvalho Chehab141276b2006-09-06 19:04:28 -030045MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, "
46 "instead of software bitbang");
Linus Torvalds1da177e2005-04-16 15:20:36 -070047module_param(i2c_scan, int, 0444);
48MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
49
Mauro Carvalho Chehab141276b2006-09-06 19:04:28 -030050static unsigned int i2c_udelay = 5;
51module_param(i2c_udelay, int, 0444);
52MODULE_PARM_DESC(i2c_udelay,"soft i2c delay at insmod time, in usecs "
53 "(should be 5 or higher). Lower value means higher bus speed.");
54
Linus Torvalds1da177e2005-04-16 15:20:36 -070055/* ----------------------------------------------------------------------- */
56/* I2C functions - bitbanging adapter (software i2c) */
57
58static void bttv_bit_setscl(void *data, int state)
59{
60 struct bttv *btv = (struct bttv*)data;
61
62 if (state)
63 btv->i2c_state |= 0x02;
64 else
65 btv->i2c_state &= ~0x02;
66 btwrite(btv->i2c_state, BT848_I2C);
67 btread(BT848_I2C);
68}
69
70static void bttv_bit_setsda(void *data, int state)
71{
72 struct bttv *btv = (struct bttv*)data;
73
74 if (state)
75 btv->i2c_state |= 0x01;
76 else
77 btv->i2c_state &= ~0x01;
78 btwrite(btv->i2c_state, BT848_I2C);
79 btread(BT848_I2C);
80}
81
82static int bttv_bit_getscl(void *data)
83{
84 struct bttv *btv = (struct bttv*)data;
85 int state;
86
87 state = btread(BT848_I2C) & 0x02 ? 1 : 0;
88 return state;
89}
90
91static int bttv_bit_getsda(void *data)
92{
93 struct bttv *btv = (struct bttv*)data;
94 int state;
95
96 state = btread(BT848_I2C) & 0x01;
97 return state;
98}
99
Jean Delvaredf9b5d42008-06-15 12:20:18 -0300100static struct i2c_algo_bit_data __devinitdata bttv_i2c_algo_bit_template = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 .setsda = bttv_bit_setsda,
102 .setscl = bttv_bit_setscl,
103 .getsda = bttv_bit_getsda,
104 .getscl = bttv_bit_getscl,
105 .udelay = 16,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 .timeout = 200,
107};
108
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109/* ----------------------------------------------------------------------- */
110/* I2C functions - hardware i2c */
111
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112static u32 functionality(struct i2c_adapter *adap)
113{
114 return I2C_FUNC_SMBUS_EMUL;
115}
116
117static int
118bttv_i2c_wait_done(struct bttv *btv)
119{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 int rc = 0;
121
Manu Abrahamfc9d53a2005-05-05 16:16:01 -0700122 /* timeout */
123 if (wait_event_interruptible_timeout(btv->i2c_queue,
124 btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
Manu Abrahamfc9d53a2005-05-05 16:16:01 -0700126 rc = -EIO;
127
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 if (btv->i2c_done & BT848_INT_RACK)
129 rc = 1;
130 btv->i2c_done = 0;
131 return rc;
132}
133
134#define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\
135 BT848_I2C_SCL | BT848_I2C_SDA)
136
137static int
138bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
139{
140 u32 xmit;
141 int retval,cnt;
142
143 /* sanity checks */
144 if (0 == msg->len)
145 return -EINVAL;
146
147 /* start, address + first byte */
148 xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW;
149 if (msg->len > 1 || !last)
150 xmit |= BT878_I2C_NOSTOP;
151 btwrite(xmit, BT848_I2C);
152 retval = bttv_i2c_wait_done(btv);
153 if (retval < 0)
154 goto err;
155 if (retval == 0)
156 goto eio;
157 if (i2c_debug) {
158 printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]);
159 if (!(xmit & BT878_I2C_NOSTOP))
160 printk(" >\n");
161 }
162
163 for (cnt = 1; cnt < msg->len; cnt++ ) {
164 /* following bytes */
165 xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART;
166 if (cnt < msg->len-1 || !last)
167 xmit |= BT878_I2C_NOSTOP;
168 btwrite(xmit, BT848_I2C);
169 retval = bttv_i2c_wait_done(btv);
170 if (retval < 0)
171 goto err;
172 if (retval == 0)
173 goto eio;
174 if (i2c_debug) {
175 printk(" %02x", msg->buf[cnt]);
176 if (!(xmit & BT878_I2C_NOSTOP))
177 printk(" >\n");
178 }
179 }
180 return msg->len;
181
182 eio:
183 retval = -EIO;
184 err:
185 if (i2c_debug)
186 printk(" ERR: %d\n",retval);
187 return retval;
188}
189
190static int
191bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
192{
193 u32 xmit;
194 u32 cnt;
195 int retval;
196
197 for(cnt = 0; cnt < msg->len; cnt++) {
198 xmit = (msg->addr << 25) | (1 << 24) | I2C_HW;
199 if (cnt < msg->len-1)
200 xmit |= BT848_I2C_W3B;
201 if (cnt < msg->len-1 || !last)
202 xmit |= BT878_I2C_NOSTOP;
203 if (cnt)
204 xmit |= BT878_I2C_NOSTART;
205 btwrite(xmit, BT848_I2C);
206 retval = bttv_i2c_wait_done(btv);
207 if (retval < 0)
208 goto err;
209 if (retval == 0)
210 goto eio;
211 msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff;
212 if (i2c_debug) {
213 if (!(xmit & BT878_I2C_NOSTART))
214 printk(" <R %02x", (msg->addr << 1) +1);
215 printk(" =%02x", msg->buf[cnt]);
216 if (!(xmit & BT878_I2C_NOSTOP))
217 printk(" >\n");
218 }
219 }
220 return msg->len;
221
222 eio:
223 retval = -EIO;
224 err:
225 if (i2c_debug)
226 printk(" ERR: %d\n",retval);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800227 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228}
229
230static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
231{
Hans Verkuil74fc7bd2009-03-14 12:36:54 -0300232 struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
233 struct bttv *btv = to_bttv(v4l2_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 int retval = 0;
235 int i;
236
237 if (i2c_debug)
238 printk("bt-i2c:");
239 btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT);
240 for (i = 0 ; i < num; i++) {
241 if (msgs[i].flags & I2C_M_RD) {
242 /* read */
243 retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num);
244 if (retval < 0)
245 goto err;
246 } else {
247 /* write */
248 retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num);
249 if (retval < 0)
250 goto err;
251 }
252 }
253 return num;
254
255 err:
256 return retval;
257}
258
Jean Delvaredf9b5d42008-06-15 12:20:18 -0300259static const struct i2c_algorithm bttv_algo = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 .master_xfer = bttv_i2c_xfer,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 .functionality = functionality,
262};
263
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264/* ----------------------------------------------------------------------- */
265/* I2C functions - common stuff */
266
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267/* read I2C */
268int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
269{
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800270 unsigned char buffer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271
272 if (0 != btv->i2c_rc)
273 return -1;
274 if (bttv_verbose && NULL != probe_for)
275 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ",
276 btv->c.nr,probe_for,addr);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800277 btv->i2c_client.addr = addr >> 1;
278 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 if (NULL != probe_for) {
280 if (bttv_verbose)
281 printk("not found\n");
282 } else
283 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n",
284 btv->c.nr,addr);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800285 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 }
287 if (bttv_verbose && NULL != probe_for)
288 printk("found\n");
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800289 return buffer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290}
291
292/* write I2C */
293int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800294 unsigned char b2, int both)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295{
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800296 unsigned char buffer[2];
297 int bytes = both ? 2 : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298
299 if (0 != btv->i2c_rc)
300 return -1;
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800301 btv->i2c_client.addr = addr >> 1;
302 buffer[0] = b1;
303 buffer[1] = b2;
304 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 return -1;
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800306 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700307}
308
309/* read EEPROM content */
310void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)
311{
Gerd Knorr5daf05f2005-05-25 12:31:26 -0700312 memset(eedata, 0, 256);
313 if (0 != btv->i2c_rc)
314 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 btv->i2c_client.addr = addr >> 1;
316 tveeprom_read(&btv->i2c_client, eedata, 256);
317}
318
319static char *i2c_devs[128] = {
Mauro Carvalho Chehab24a70fd2005-09-09 13:03:39 -0700320 [ 0x1c >> 1 ] = "lgdt330x",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 [ 0x30 >> 1 ] = "IR (hauppauge)",
322 [ 0x80 >> 1 ] = "msp34xx",
323 [ 0x86 >> 1 ] = "tda9887",
324 [ 0xa0 >> 1 ] = "eeprom",
325 [ 0xc0 >> 1 ] = "tuner (analog)",
326 [ 0xc2 >> 1 ] = "tuner (analog)",
327};
328
329static void do_i2c_scan(char *name, struct i2c_client *c)
330{
331 unsigned char buf;
332 int i,rc;
333
Mauro Carvalho Chehab53c4e952007-03-29 08:42:30 -0300334 for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 c->addr = i;
336 rc = i2c_master_recv(c,&buf,0);
337 if (rc < 0)
338 continue;
339 printk("%s: i2c scan: found device @ 0x%x [%s]\n",
340 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
341 }
342}
343
344/* init + register i2c algo-bit adapter */
345int __devinit init_bttv_i2c(struct bttv *btv)
346{
Jean Delvaredf9b5d42008-06-15 12:20:18 -0300347 strlcpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348
349 if (i2c_hw)
350 btv->use_i2c_hw = 1;
351 if (btv->use_i2c_hw) {
352 /* bt878 */
Jean Delvaredf9b5d42008-06-15 12:20:18 -0300353 strlcpy(btv->c.i2c_adap.name, "bt878",
354 sizeof(btv->c.i2c_adap.name));
355 btv->c.i2c_adap.id = I2C_HW_B_BT848; /* FIXME */
356 btv->c.i2c_adap.algo = &bttv_algo;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 } else {
358 /* bt848 */
Mauro Carvalho Chehab141276b2006-09-06 19:04:28 -0300359 /* Prevents usage of invalid delay values */
360 if (i2c_udelay<5)
361 i2c_udelay=5;
Mauro Carvalho Chehab141276b2006-09-06 19:04:28 -0300362
Jean Delvaredf9b5d42008-06-15 12:20:18 -0300363 strlcpy(btv->c.i2c_adap.name, "bttv",
364 sizeof(btv->c.i2c_adap.name));
365 btv->c.i2c_adap.id = I2C_HW_B_BT848;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template,
367 sizeof(bttv_i2c_algo_bit_template));
Jean Delvaredf9b5d42008-06-15 12:20:18 -0300368 btv->i2c_algo.udelay = i2c_udelay;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 btv->i2c_algo.data = btv;
370 btv->c.i2c_adap.algo_data = &btv->i2c_algo;
371 }
Jean Delvaredf9b5d42008-06-15 12:20:18 -0300372 btv->c.i2c_adap.owner = THIS_MODULE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
374 btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
375 snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
376 "bt%d #%d [%s]", btv->id, btv->c.nr,
377 btv->use_i2c_hw ? "hw" : "sw");
378
Hans Verkuil74fc7bd2009-03-14 12:36:54 -0300379 i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800380 btv->i2c_client.adapter = &btv->c.i2c_adap;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382
383 if (btv->use_i2c_hw) {
384 btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
385 } else {
386 bttv_bit_setscl(btv,1);
387 bttv_bit_setsda(btv,1);
388 btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap);
389 }
390 if (0 == btv->i2c_rc && i2c_scan)
Hans Verkuil74fc7bd2009-03-14 12:36:54 -0300391 do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
Jean Delvarec668f322009-05-13 16:48:50 -0300392
393 /* Instantiate the IR receiver device, if present */
394 if (0 == btv->i2c_rc) {
395 struct i2c_board_info info;
396 /* The external IR receiver is at i2c address 0x34 (0x35 for
397 reads). Future Hauppauge cards will have an internal
398 receiver at 0x30 (0x31 for reads). In theory, both can be
399 fitted, and Hauppauge suggest an external overrides an
400 internal.
401
402 That's why we probe 0x1a (~0x34) first. CB
403 */
404 const unsigned short addr_list[] = {
405 0x1a, 0x18, 0x4b, 0x64, 0x30,
406 I2C_CLIENT_END
407 };
408
409 memset(&info, 0, sizeof(struct i2c_board_info));
410 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
411 i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list);
412 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 return btv->i2c_rc;
414}
415
416int __devexit fini_bttv_i2c(struct bttv *btv)
417{
418 if (0 != btv->i2c_rc)
419 return 0;
420
Jean Delvare32697112006-12-10 21:21:33 +0100421 return i2c_del_adapter(&btv->c.i2c_adap);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422}
423
424/*
425 * Local variables:
426 * c-basic-offset: 8
427 * End:
428 */