-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Mauro Carvalho Chehab
committed
Dec 10, 2006
1 parent
106593c
commit f69c8a7
Showing
9 changed files
with
6,850 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 2a893dea0f186efc2eb4bcdaee145b20c87d239d | ||
refs/heads/master: 781aa1d1ab7ba13314af0af6c5d70c0eb0e96bf4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
usbvision-objs := usbvision-core.o usbvision-i2c.o | ||
|
||
obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o | ||
|
||
EXTRA_CFLAGS += -Idrivers/media/video |
5,880 changes: 5,880 additions & 0 deletions
5,880
trunk/drivers/media/video/usbvision/usbvision-core.c
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,265 @@ | ||
/* | ||
* I2C_ALGO_USB.C | ||
* i2c algorithm for USB-I2C Bridges | ||
* | ||
* Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de> | ||
* Dwaine Garden <dwainegarden@rogers.com> | ||
* | ||
* This module is part of usbvision driver project. | ||
* Updates to driver completed by Dwaine P. Garden | ||
* | ||
* 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 | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
|
||
|
||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
#include <linux/delay.h> | ||
#include <linux/slab.h> | ||
#include <linux/version.h> | ||
#include <linux/utsname.h> | ||
#include <linux/init.h> | ||
#include <asm/uaccess.h> | ||
#include <linux/ioport.h> | ||
#include <linux/errno.h> | ||
#include <linux/sched.h> | ||
#include <linux/usb.h> | ||
#include <linux/i2c.h> | ||
#include "usbvision-i2c.h" | ||
|
||
static int debug = 0; | ||
|
||
#if defined(module_param) // Showing parameters under SYSFS | ||
module_param (debug, int, 0444); // debug mode of the device driver | ||
#else | ||
MODULE_PARM(debug, "i"); // debug mode of the device driver | ||
#endif | ||
|
||
MODULE_AUTHOR("Joerg Heckenbach"); | ||
MODULE_DESCRIPTION("I2C algorithm for USB-I2C-bridges"); | ||
MODULE_LICENSE("GPL"); | ||
|
||
|
||
static inline int try_write_address(struct i2c_adapter *i2c_adap, | ||
unsigned char addr, int retries) | ||
{ | ||
struct i2c_algo_usb_data *adap = i2c_adap->algo_data; | ||
void *data; | ||
int i, ret = -1; | ||
char buf[4]; | ||
|
||
data = i2c_get_adapdata(i2c_adap); | ||
buf[0] = 0x00; | ||
for (i = 0; i <= retries; i++) { | ||
ret = (adap->outb(data, addr, buf, 1)); | ||
if (ret == 1) | ||
break; /* success! */ | ||
udelay(5 /*adap->udelay */ ); | ||
if (i == retries) /* no success */ | ||
break; | ||
udelay(adap->udelay); | ||
} | ||
if (debug) { | ||
if (i) { | ||
info("%s: Needed %d retries for address %#2x", __FUNCTION__, i, addr); | ||
info("%s: Maybe there's no device at this address", __FUNCTION__); | ||
} | ||
} | ||
return ret; | ||
} | ||
|
||
static inline int try_read_address(struct i2c_adapter *i2c_adap, | ||
unsigned char addr, int retries) | ||
{ | ||
struct i2c_algo_usb_data *adap = i2c_adap->algo_data; | ||
void *data; | ||
int i, ret = -1; | ||
char buf[4]; | ||
|
||
data = i2c_get_adapdata(i2c_adap); | ||
for (i = 0; i <= retries; i++) { | ||
ret = (adap->inb(data, addr, buf, 1)); | ||
if (ret == 1) | ||
break; /* success! */ | ||
udelay(5 /*adap->udelay */ ); | ||
if (i == retries) /* no success */ | ||
break; | ||
udelay(adap->udelay); | ||
} | ||
if (debug) { | ||
if (i) { | ||
info("%s: Needed %d retries for address %#2x", __FUNCTION__, i, addr); | ||
info("%s: Maybe there's no device at this address", __FUNCTION__); | ||
} | ||
} | ||
return ret; | ||
} | ||
|
||
static inline int usb_find_address(struct i2c_adapter *i2c_adap, | ||
struct i2c_msg *msg, int retries, | ||
unsigned char *add) | ||
{ | ||
unsigned short flags = msg->flags; | ||
|
||
unsigned char addr; | ||
int ret; | ||
if ((flags & I2C_M_TEN)) { | ||
/* a ten bit address */ | ||
addr = 0xf0 | ((msg->addr >> 7) & 0x03); | ||
/* try extended address code... */ | ||
ret = try_write_address(i2c_adap, addr, retries); | ||
if (ret != 1) { | ||
err("died at extended address code, while writing"); | ||
return -EREMOTEIO; | ||
} | ||
add[0] = addr; | ||
if (flags & I2C_M_RD) { | ||
/* okay, now switch into reading mode */ | ||
addr |= 0x01; | ||
ret = try_read_address(i2c_adap, addr, retries); | ||
if (ret != 1) { | ||
err("died at extended address code, while reading"); | ||
return -EREMOTEIO; | ||
} | ||
} | ||
|
||
} else { /* normal 7bit address */ | ||
addr = (msg->addr << 1); | ||
if (flags & I2C_M_RD) | ||
addr |= 1; | ||
if (flags & I2C_M_REV_DIR_ADDR) | ||
addr ^= 1; | ||
|
||
add[0] = addr; | ||
if (flags & I2C_M_RD) | ||
ret = try_read_address(i2c_adap, addr, retries); | ||
else | ||
ret = try_write_address(i2c_adap, addr, retries); | ||
|
||
if (ret != 1) { | ||
return -EREMOTEIO; | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
static int | ||
usb_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) | ||
{ | ||
struct i2c_msg *pmsg; | ||
struct i2c_algo_usb_data *adap = i2c_adap->algo_data; | ||
void *data; | ||
int i, ret; | ||
unsigned char addr; | ||
|
||
data = i2c_get_adapdata(i2c_adap); | ||
|
||
for (i = 0; i < num; i++) { | ||
pmsg = &msgs[i]; | ||
ret = usb_find_address(i2c_adap, pmsg, i2c_adap->retries, &addr); | ||
if (ret != 0) { | ||
if (debug) { | ||
info("%s: got NAK from device, message #%d\n", __FUNCTION__, i); | ||
} | ||
return (ret < 0) ? ret : -EREMOTEIO; | ||
} | ||
|
||
if (pmsg->flags & I2C_M_RD) { | ||
/* read bytes into buffer */ | ||
ret = (adap->inb(data, addr, pmsg->buf, pmsg->len)); | ||
if (ret < pmsg->len) { | ||
return (ret < 0) ? ret : -EREMOTEIO; | ||
} | ||
} else { | ||
/* write bytes from buffer */ | ||
ret = (adap->outb(data, addr, pmsg->buf, pmsg->len)); | ||
if (ret < pmsg->len) { | ||
return (ret < 0) ? ret : -EREMOTEIO; | ||
} | ||
} | ||
} | ||
return num; | ||
} | ||
|
||
static int algo_control(struct i2c_adapter *adapter, unsigned int cmd, unsigned long arg) | ||
{ | ||
return 0; | ||
} | ||
|
||
static u32 usb_func(struct i2c_adapter *adap) | ||
{ | ||
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; | ||
} | ||
|
||
|
||
/* -----exported algorithm data: ------------------------------------- */ | ||
|
||
static struct i2c_algorithm i2c_usb_algo = { | ||
.master_xfer = usb_xfer, | ||
.smbus_xfer = NULL, | ||
.slave_send = NULL, | ||
.slave_recv = NULL, | ||
.algo_control = algo_control, | ||
.functionality = usb_func, | ||
}; | ||
|
||
|
||
/* | ||
* registering functions to load algorithms at runtime | ||
*/ | ||
int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap) | ||
{ | ||
/* register new adapter to i2c module... */ | ||
|
||
adap->algo = &i2c_usb_algo; | ||
|
||
adap->timeout = 100; /* default values, should */ | ||
adap->retries = 3; /* be replaced by defines */ | ||
|
||
#ifdef MODULE | ||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 21) | ||
MOD_INC_USE_COUNT; | ||
#endif | ||
#endif | ||
|
||
i2c_add_adapter(adap); | ||
|
||
if (debug) { | ||
info("i2c bus for %s registered", adap->name); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
|
||
int usbvision_i2c_usb_del_bus(struct i2c_adapter *adap) | ||
{ | ||
|
||
i2c_del_adapter(adap); | ||
|
||
if (debug) { | ||
info("i2c bus for %s unregistered", adap->name); | ||
} | ||
#ifdef MODULE | ||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 21) | ||
MOD_DEC_USE_COUNT; | ||
#endif | ||
#endif | ||
|
||
return 0; | ||
} | ||
|
||
EXPORT_SYMBOL(usbvision_i2c_usb_add_bus); | ||
EXPORT_SYMBOL(usbvision_i2c_usb_del_bus); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* I2C_ALGO_USB.H | ||
* i2c algorithm for USB-I2C Bridges | ||
* | ||
* Copyright (c) 1999-2005 Joerg Heckenbach <joerg@heckenbach-aw.de> | ||
* | ||
* This module is part of usbvision driver project. | ||
* Updates to driver completed by Dwaine P. Garden | ||
* | ||
* 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 | ||
* the Free Software Foundation; either version 2 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
|
||
|
||
#ifndef I2C_ALGO_USB_H | ||
#define I2C_ALGO_USB_H 1 | ||
|
||
#include <linux/i2c.h> | ||
|
||
struct i2c_algo_usb_data { | ||
void *data; /* private data for lowlevel routines */ | ||
int (*inb) (void *data, unsigned char addr, char *buf, short len); | ||
int (*outb) (void *data, unsigned char addr, char *buf, short len); | ||
|
||
/* local settings */ | ||
int udelay; | ||
int mdelay; | ||
int timeout; | ||
}; | ||
|
||
#define I2C_USB_ADAP_MAX 16 | ||
|
||
int usbvision_i2c_usb_add_bus(struct i2c_adapter *); | ||
int usbvision_i2c_usb_del_bus(struct i2c_adapter *); | ||
|
||
static inline void *i2c_get_algo_usb_data (struct i2c_algo_usb_data *dev) | ||
{ | ||
return dev->data; | ||
} | ||
|
||
static inline void i2c_set_algo_usb_data (struct i2c_algo_usb_data *dev, void *data) | ||
{ | ||
dev->data = data; | ||
} | ||
|
||
|
||
#endif //I2C_ALGO_USB_H |
Oops, something went wrong.