Commit 141276b5 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

V4L/DVB (4609): Improved i2c performance on software bitbang algoritm

Software I2C were using a very conservative value of udelay=16, meaning about
20Kbps. According with Philips I2C datasheet, the i2c should answer well for
times at the order of 4.7 us. So, using udelay=5 should work for all devices.
After this patch, the speed should be close to 66,67 Kbps, with the current
kernel software bitbang, with 30/60 duty cycle.
Anyway, added a new parameter (i2c_udelay) that would allow using conservative
values, if eventually a hardware doesn't support the datasheet values.
Thanks to Jean Delvare <khali@linux-fr.org> for pointing this improvement.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 48c06d5e
...@@ -54,6 +54,12 @@ bttv.o ...@@ -54,6 +54,12 @@ bttv.o
dropouts. dropouts.
chroma_agc=0/1 AGC of chroma signal, off by default. chroma_agc=0/1 AGC of chroma signal, off by default.
adc_crush=0/1 Luminance ADC crush, on by default. adc_crush=0/1 Luminance ADC crush, on by default.
i2c_udelay= Allow reduce I2C speed. Default is 5 usecs
(meaning 66,67 Kbps). The default is the
maximum supported speed by kernel bitbang
algoritm. You may use lower numbers, if I2C
messages are lost (16 is known to work on
all supported cards).
bttv_gpio=0/1 bttv_gpio=0/1
gpiomask= gpiomask=
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
& Marcus Metzler (mocm@thp.uni-koeln.de) & Marcus Metzler (mocm@thp.uni-koeln.de)
(c) 1999-2003 Gerd Knorr <kraxel@bytesex.org> (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
(c) 2005 Mauro Carvalho Chehab <mchehab@infradead.org>
- Multituner support and i2c address binding
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
...@@ -45,10 +48,18 @@ static int i2c_debug; ...@@ -45,10 +48,18 @@ static int i2c_debug;
static int i2c_hw; static int i2c_hw;
static int i2c_scan; static int i2c_scan;
module_param(i2c_debug, int, 0644); module_param(i2c_debug, int, 0644);
MODULE_PARM_DESC(i2c_hw,"configure i2c debug level");
module_param(i2c_hw, int, 0444); module_param(i2c_hw, int, 0444);
MODULE_PARM_DESC(i2c_hw,"force use of hardware i2c support, "
"instead of software bitbang");
module_param(i2c_scan, int, 0444); module_param(i2c_scan, int, 0444);
MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
static unsigned int i2c_udelay = 5;
module_param(i2c_udelay, int, 0444);
MODULE_PARM_DESC(i2c_udelay,"soft i2c delay at insmod time, in usecs "
"(should be 5 or higher). Lower value means higher bus speed.");
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* I2C functions - bitbanging adapter (software i2c) */ /* I2C functions - bitbanging adapter (software i2c) */
...@@ -426,6 +437,11 @@ int __devinit init_bttv_i2c(struct bttv *btv) ...@@ -426,6 +437,11 @@ int __devinit init_bttv_i2c(struct bttv *btv)
sizeof(bttv_i2c_adap_hw_template)); sizeof(bttv_i2c_adap_hw_template));
} else { } else {
/* bt848 */ /* bt848 */
/* Prevents usage of invalid delay values */
if (i2c_udelay<5)
i2c_udelay=5;
bttv_i2c_algo_bit_template.udelay=i2c_udelay;
memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_sw_template, memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_sw_template,
sizeof(bttv_i2c_adap_sw_template)); sizeof(bttv_i2c_adap_sw_template));
memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template, memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template,
......
...@@ -43,6 +43,11 @@ static unsigned int i2c_scan = 0; ...@@ -43,6 +43,11 @@ static unsigned int i2c_scan = 0;
module_param(i2c_scan, int, 0444); module_param(i2c_scan, int, 0444);
MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
static unsigned int i2c_udelay = 5;
module_param(i2c_udelay, int, 0644);
MODULE_PARM_DESC(i2c_udelay,"i2c delay at insmod time, in usecs "
"(should be 5 or higher). Lower value means higher bus speed.");
#define dprintk(level,fmt, arg...) if (i2c_debug >= level) \ #define dprintk(level,fmt, arg...) if (i2c_debug >= level) \
printk(KERN_DEBUG "%s: " fmt, core->name , ## arg) printk(KERN_DEBUG "%s: " fmt, core->name , ## arg)
...@@ -202,6 +207,11 @@ static void do_i2c_scan(char *name, struct i2c_client *c) ...@@ -202,6 +207,11 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
/* init + register i2c algo-bit adapter */ /* init + register i2c algo-bit adapter */
int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci) int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
{ {
/* Prevents usage of invalid delay values */
if (i2c_udelay<5)
i2c_udelay=5;
cx8800_i2c_algo_template.udelay=i2c_udelay;
memcpy(&core->i2c_adap, &cx8800_i2c_adap_template, memcpy(&core->i2c_adap, &cx8800_i2c_adap_template,
sizeof(core->i2c_adap)); sizeof(core->i2c_adap));
memcpy(&core->i2c_algo, &cx8800_i2c_algo_template, memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment