Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 113997
b: refs/heads/master
c: bdc203e
h: refs/heads/master
i:
  113995: 541e475
v: v3
  • Loading branch information
Devin Heitmueller authored and Mauro Carvalho Chehab committed Oct 12, 2008
1 parent b7fa7b7 commit 5fe0dec
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 17a370bcca661a849c9af07feae86f42d0c6dfd1
refs/heads/master: bdc203e156ce938e12d957912bd29ca53d160540
3 changes: 3 additions & 0 deletions trunk/drivers/media/dvb/dvb-usb/dib0700.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ extern int dvb_usb_dib0700_debug;
// 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
#define REQUEST_SET_RC 0x11
#define REQUEST_NEW_I2C_READ 0x12
#define REQUEST_NEW_I2C_WRITE 0x13
#define REQUEST_GET_VERSION 0x15

struct dib0700_state {
Expand All @@ -39,6 +41,7 @@ struct dib0700_state {
u8 rc_toggle;
u8 rc_counter;
u8 is_dib7000pc;
u8 fw_use_new_i2c_api;
};

extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
Expand Down
108 changes: 106 additions & 2 deletions trunk/drivers/media/dvb/dvb-usb/dib0700_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,98 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_
}

/*
* I2C master xfer function
* I2C master xfer function (supported in 1.20 firmware)
*/
static int dib0700_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num)
static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
int num)
{
/* The new i2c firmware messages are more reliable and in particular
properly support i2c read calls not preceded by a write */

struct dvb_usb_device *d = i2c_get_adapdata(adap);
uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */
uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
uint8_t en_start = 0;
uint8_t en_stop = 0;
uint8_t buf[255]; /* TBV: malloc ? */
int result, i;

/* Ensure nobody else hits the i2c bus while we're sending our
sequence of messages, (such as the remote control thread) */
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;

for (i = 0; i < num; i++) {
if (i == 0) {
/* First message in the transaction */
en_start = 1;
} else if (!(msg[i].flags & I2C_M_NOSTART)) {
/* Device supports repeated-start */
en_start = 1;
} else {
/* Not the first packet and device doesn't support
repeated start */
en_start = 0;
}
if (i == (num - 1)) {
/* Last message in the transaction */
en_stop = 1;
}

if (msg[i].flags & I2C_M_RD) {
/* Read request */
u16 index, value;
uint8_t i2c_dest;

i2c_dest = (msg[i].addr << 1);
value = ((en_start << 7) | (en_stop << 6) |
(msg[i].len & 0x3F)) << 8 | i2c_dest;
/* I2C ctrl + FE bus; */
index = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30);

result = usb_control_msg(d->udev,
usb_rcvctrlpipe(d->udev, 0),
REQUEST_NEW_I2C_READ,
USB_TYPE_VENDOR | USB_DIR_IN,
value, index, msg[i].buf,
msg[i].len,
USB_CTRL_GET_TIMEOUT);
if (result < 0) {
err("i2c read error (status = %d)\n", result);
break;
}
} else {
/* Write request */
buf[0] = REQUEST_NEW_I2C_WRITE;
buf[1] = (msg[i].addr << 1);
buf[2] = (en_start << 7) | (en_stop << 6) |
(msg[i].len & 0x3F);
/* I2C ctrl + FE bus; */
buf[3] = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30);
/* The Actual i2c payload */
memcpy(&buf[4], msg[i].buf, msg[i].len);

result = usb_control_msg(d->udev,
usb_sndctrlpipe(d->udev, 0),
REQUEST_NEW_I2C_WRITE,
USB_TYPE_VENDOR | USB_DIR_OUT,
0, 0, buf, msg[i].len + 4,
USB_CTRL_GET_TIMEOUT);
if (result < 0) {
err("i2c write error (status = %d)\n", result);
break;
}
}
}
mutex_unlock(&d->i2c_mutex);
return i;
}

/*
* I2C master xfer function (pre-1.20 firmware)
*/
static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
struct i2c_msg *msg, int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int i,len;
Expand Down Expand Up @@ -124,6 +213,21 @@ static int dib0700_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg *msg,int num
return i;
}

static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
struct dib0700_state *st = d->priv;

if (st->fw_use_new_i2c_api == 1) {
/* User running at least fw 1.20 */
return dib0700_i2c_xfer_new(adap, msg, num);
} else {
/* Use legacy calls */
return dib0700_i2c_xfer_legacy(adap, msg, num);
}
}

static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C;
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,7 @@ MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
.caps = DVB_USB_IS_AN_I2C_ADAPTER, \
.usb_ctrl = DEVICE_SPECIFIC, \
.firmware = "dvb-usb-dib0700-1.10.fw", \
.firmware = "dvb-usb-dib0700-1.20.fw", \
.download_firmware = dib0700_download_firmware, \
.no_reconnect = 1, \
.size_of_priv = sizeof(struct dib0700_state), \
Expand Down

0 comments on commit 5fe0dec

Please sign in to comment.