#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>
#define DBG_I2C 1<<0
-static int i2c_debug = 0;
+static int i2c_debug;
module_param (i2c_debug, int, 0644); // debug_i2c_usb mode of the device driver
MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
-#define PDEBUG(level, fmt, args...) \
- if (i2c_debug & (level)) info("[%s:%d] " fmt, __PRETTY_FUNCTION__, __LINE__ , ## args)
+#define PDEBUG(level, fmt, args...) { \
+ if (i2c_debug & (level)) \
+ printk(KERN_INFO KBUILD_MODNAME ":[%s:%d] " fmt, \
+ __func__, __LINE__ , ## args); \
+ }
static int usbvision_i2c_write(struct usb_usbvision *usbvision, unsigned char addr, char *buf,
short len);
int i, ret = -1;
char buf[4];
- usbvision = i2c_get_adapdata(i2c_adap);
+ usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
buf[0] = 0x00;
for (i = 0; i <= retries; i++) {
ret = (usbvision_i2c_write(usbvision, addr, buf, 1));
int i, ret = -1;
char buf[4];
- usbvision = i2c_get_adapdata(i2c_adap);
+ usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
for (i = 0; i <= retries; i++) {
ret = (usbvision_i2c_read(usbvision, addr, buf, 1));
if (ret == 1)
/* try extended address code... */
ret = try_write_address(i2c_adap, addr, retries);
if (ret != 1) {
- err("died at extended address code, while writing");
+ dev_err(&i2c_adap->dev,
+ "died at extended address code, while writing\n");
return -EREMOTEIO;
}
add[0] = addr;
addr |= 0x01;
ret = try_read_address(i2c_adap, addr, retries);
if (ret != 1) {
- err("died at extended address code, while reading");
+ dev_err(&i2c_adap->dev,
+ "died at extended address code, while reading\n");
return -EREMOTEIO;
}
}
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)
struct i2c_msg *pmsg;
struct usb_usbvision *usbvision;
int i, ret;
- unsigned char addr;
+ unsigned char addr = 0;
+
+ usbvision = (struct usb_usbvision *)i2c_get_adapdata(i2c_adap);
- usbvision = 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);
return num;
}
-static int algo_control(struct i2c_adapter *adapter, unsigned int cmd, unsigned long arg)
-{
- return 0;
-}
-
static u32 functionality(struct i2c_adapter *adap)
{
- return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
+ return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
}
-
/* -----exported algorithm data: ------------------------------------- */
static struct i2c_algorithm usbvision_algo = {
.master_xfer = usbvision_i2c_xfer,
.smbus_xfer = NULL,
- .algo_control = algo_control,
.functionality = functionality,
};
/* usbvision specific I2C functions */
/* ----------------------------------------------------------------------- */
static struct i2c_adapter i2c_adap_template;
-static struct i2c_client i2c_client_template;
int usbvision_i2c_register(struct usb_usbvision *usbvision)
{
- int ret;
-
- usbvision->i2c_adap = i2c_adap_template;
- usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
+ static unsigned short saa711x_addrs[] = {
+ 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
+ 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
+ I2C_CLIENT_END };
- PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
+ memcpy(&usbvision->i2c_adap, &i2c_adap_template,
+ sizeof(struct i2c_adapter));
sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name),
- " #%d", usbvision->vdev->minor & 0x1f);
- PDEBUG(DBG_I2C,"I2C Registering adaptername: %s", usbvision->i2c_adap.name);
- i2c_set_adapdata(&usbvision->i2c_adap,usbvision);
- if ((ret = i2c_add_adapter(&usbvision->i2c_adap)) < 0) {
- PDEBUG(DBG_I2C,"could not add I2C adapter %s", usbvision->i2c_adap.name);
- return ret;
- }
+ " #%d", usbvision->vdev->num);
+ PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name);
+ usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
- /* TODO: use i2c_client for eeprom detection as an example... */
- usbvision->i2c_client = i2c_client_template;
- usbvision->i2c_client.adapter = &usbvision->i2c_adap;
+ i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);
if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
- printk(KERN_ERR "usbvision_i2c_register: can't write reg\n");
+ printk(KERN_ERR "usbvision_register: can't write reg\n");
return -EBUSY;
}
-#ifdef CONFIG_MODULES
+ PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
+ PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]");
+
+ /* register new adapter to i2c module... */
+
+ usbvision->i2c_adap.algo = &usbvision_algo;
+
+ usbvision->i2c_adap.timeout = 100; /* default values, should */
+ usbvision->i2c_adap.retries = 3; /* be replaced by defines */
+
+ i2c_add_adapter(&usbvision->i2c_adap);
+
+ PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name);
+
/* Request the load of the i2c modules we need */
switch (usbvision_device_data[usbvision->DevModel].Codec) {
case CODEC_SAA7113:
- request_module("saa7115");
- break;
case CODEC_SAA7111:
- request_module("saa7115");
+ v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+ &usbvision->i2c_adap, "saa7115",
+ "saa7115_auto", saa711x_addrs);
break;
}
if (usbvision_device_data[usbvision->DevModel].Tuner == 1) {
- request_module("tuner");
+ struct v4l2_subdev *sd;
+ enum v4l2_i2c_tuner_type type;
+ struct tuner_setup tun_setup;
+
+ sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+ &usbvision->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ /* depending on whether we found a demod or not, select
+ the tuner type. */
+ type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+
+ sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev,
+ &usbvision->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(type));
+
+ if (usbvision->tuner_type != -1) {
+ tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+ tun_setup.type = usbvision->tuner_type;
+ tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+ call_all(usbvision, tuner, s_type_addr, &tun_setup);
+ }
}
-#endif
return 0;
}
return 0;
}
-void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,
- void *arg)
-{
- i2c_clients_command(&usbvision->i2c_adap, cmd, arg);
-}
-
-static int attach_inform(struct i2c_client *client)
-{
- struct usb_usbvision *usbvision;
-
- usbvision = i2c_get_adapdata(client->adapter);
- switch (client->addr << 1) {
- case 0x42 << 1:
- case 0x43 << 1:
- case 0x4a << 1:
- case 0x4b << 1:
- {
- struct tuner_setup tun_setup;
-
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = TUNER_TDA9887;
- tun_setup.addr = client->addr;
-
- call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup);
-
- break;
- }
- case 0x42:
- PDEBUG(DBG_I2C,"attach_inform: saa7114 detected.");
- break;
- case 0x4a:
- PDEBUG(DBG_I2C,"attach_inform: saa7113 detected.");
- break;
- case 0x48:
- PDEBUG(DBG_I2C,"attach_inform: saa7111 detected.");
- break;
- case 0xa0:
- PDEBUG(DBG_I2C,"attach_inform: eeprom detected.");
- break;
-
- default:
- {
- struct tuner_setup tun_setup;
-
- PDEBUG(DBG_I2C,"attach inform: detected I2C address %x", client->addr << 1);
- usbvision->tuner_addr = client->addr;
-
- if ((usbvision->have_tuner) && (usbvision->tuner_type != -1)) {
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = usbvision->tuner_type;
- tun_setup.addr = usbvision->tuner_addr;
- call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup);
- }
- }
- break;
- }
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct usb_usbvision *usbvision;
-
- usbvision = i2c_get_adapdata(client->adapter);
-
- PDEBUG(DBG_I2C,"usbvision[%d] detaches %s", usbvision->nr, client->name);
- return 0;
-}
-
static int
usbvision_i2c_read_max4(struct usb_usbvision *usbvision, unsigned char addr,
char *buf, short len)
static struct i2c_adapter i2c_adap_template = {
.owner = THIS_MODULE,
.name = "usbvision",
- .id = I2C_HW_B_BT848, /* FIXME */
- .algo = &usbvision_algo,
- .algo_data = NULL,
- .client_register = attach_inform,
- .client_unregister = detach_inform,
-#ifdef I2C_ADAP_CLASS_TV_ANALOG
- .class = I2C_ADAP_CLASS_TV_ANALOG,
-#else
- .class = I2C_CLASS_TV_ANALOG,
-#endif
-};
-
-static struct i2c_client i2c_client_template = {
- .name = "usbvision internal",
};
/*