tm6000 fix i2c
Subsystems (2)
PATCH 1/1 tm6000 fix i2c
Hi
Rework I2C for read word from connected devices, now it works well. Add new functions for read/write blocks.
linux/drivers/staging/tm6000/tm6000-i2c.c +144 -9
@@ -24,6 +24,7 @@#include <linux/kernel.h> #include <linux/usb.h> #include <linux/i2c.h> +#include <linux/delay.h> #include "compat.h" #include "tm6000.h"
@@ -45,11 +46,39 @@printk (KERN_DEBUG "%s at %s: " fmt, \ dev->name, __FUNCTION__ , ##args); } while (0) +static void tm6000_i2c_reset(struct tm6000_core *dev) +{ +tm6000_set_reg (dev,REQ_03_SET_GET_MCU_PIN ,TM6000_GPIO_CLK ,0 ); +msleep (15 ); +tm6000_set_reg (dev,REQ_03_SET_GET_MCU_PIN ,TM6000_GPIO_CLK ,1 ); +msleep (15 ); +} +static int tm6000_i2c_send_regs (struct tm6000_core *dev,unsigned char addr,__u8 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , buf, len); +int rc; +unsigned int tsleep; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf, len); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len *200 ) +200 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; }/* Generic read - doesn't work fine with 16bit registers */
@@ -59,22 +88,30 @@int rc;u8 b[2 ]; -if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) && (reg %2 ==0 )) { +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ +if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) + && (reg %2 ==0 )) {/* * Workaround an I2C bug when reading from zl10353 */ reg -=1 ; len +=1 ; - rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , b, len); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , b, len); *buf = b[1 ]; }else { - rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , buf, len); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf, len); } +/* release mutex */ return rc; }
@@ -85,8 +122,106 @@static int tm6000_i2c_recv_regs16 (struct tm6000_core *dev,unsigned char addr,__u16 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_14_SET_GET_I2C_WR2_RDN , addr, reg, buf, len); +int rc; +unsigned char ureg; + +if (!buf || len !=2 ) +return -1 ; + +/* capture mutex */ + ureg = reg &0xFF ; + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | (reg &0xFF00 ),0 , &ureg,1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +msleep (1400 /1000 ); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_35_AFTEK_TUNER_READ , + reg,0 , buf, len); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* release mutex */ +return rc; +} + +static int tm6000_i2c_read_sequence (struct tm6000_core *dev,unsigned char addr, +__u16 reg,char *buf,int len) +{ +int rc; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_35_AFTEK_TUNER_READ , + reg,0 , buf, len); +/* release mutex */ +return rc; +} + +static int tm6000_i2c_write_sequence (struct tm6000_core *dev, +unsigned char addr,__u16 reg,char *buf, +int len) +{ +int rc; +unsigned int tsleep; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf+1 , len-1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len *200 ) +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; +} + +static int tm6000_i2c_write_uni (struct tm6000_core *dev,unsigned char addr, +__u16 reg,char *buf,int len) +{ +int rc; +unsigned int tsleep; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_30_I2C_WRITE , + addr | reg <<8 ,0 , buf+1 , len-1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len *200 ) +1000 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; } static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
With my best regards, Dmitry.
linux/drivers/staging/tm6000/tm6000-i2c.c +144 -9
191 lines not on this page · raw message
I am still able to watch tv after applying the patch but the return code is bad and is causing unnecessary reloading of the same firmwares.
[ 2482.599040] usb 1-1: firmware: requesting tm6000-xc3028.fw [ 2482.607229] xc2028 2-0061: Loading 77 firmware images from tm6000-xc3028.fw, type: xc2028 firmware, ver 2.4 [ 2482.788089] xc2028 2-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000. [ 2503.620069] (0), id 00000000000000ff: [ 2503.620078] xc2028 2-0061: Loading firmware for type=(0), id 0000000100000007. [ 2504.380061] xc2028 2-0061: Loading SCODE for type=MONO SCODE HAS_IF_5320 (60008000), id 0000000f00000007. [ 2504.520063] xc2028 2-0061: i2c input error: rc = -32 (should be 2) [ 2504.536064] xc2028 2-0061: Unable to read tuner registers. [ 2504.776079] xc2028 2-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000. [ 2525.556048] (0), id 00000000000000ff: [ 2525.556057] xc2028 2-0061: Loading firmware for type=(0), id 0000000100000007. [ 2526.312058] xc2028 2-0061: Loading SCODE for type=MONO SCODE HAS_IF_5320 (60008000), id 0000000f00000007. [ 2526.452061] xc2028 2-0061: i2c input error: rc = -32 (should be 2) [ 2526.468050] xc2028 2-0061: Unable to read tuner registers. [ 2527.648076] xc2028 2-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000. [ 2548.460067] (0), id 00000000000000ff: [ 2548.460076] xc2028 2-0061: Loading firmware for type=(0), id 0000000100000007. [ 2549.216070] xc2028 2-0061: Loading SCODE for type=MONO SCODE HAS_IF_5320 (60008000), id 0000000f00000007. [ 2549.356064] xc2028 2-0061: i2c input error: rc = -32 (should be 2) [ 2549.372065] xc2028 2-0061: Unable to read tuner registers. [ 2549.612052] xc2028 2-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000. [ 2570.609041] (0), id 00000000000000ff: [ 2570.609049] xc2028 2-0061: Loading firmware for type=(0), id 0000000100000007. [ 2571.397034] xc2028 2-0061: Loading SCODE for type=MONO SCODE HAS_IF_5320 (60008000), id 0000000f00000007. [ 2571.537025] xc2028 2-0061: i2c input error: rc = -32 (should be 2) [ 2571.553024] xc2028 2-0061: Unable to read tuner registers. [ 2572.553103] Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: 0) [ 2572.561090] tm6000: open called (dev=video0) [ 2573.081022] Original value=96 [ 2573.093037] tm6000: VIDIOC_QUERYCAP [ 2573.149565] tm6000: open called (dev=video0)
Quoted 208 lines · Dmitri Belimov
Hi
Rework I2C for read word from connected devices, now it works well. Add new functions for read/write blocks.
diff -r
7c0b887911cflinux/drivers/staging/tm6000/tm6000-i2c.clinux/drivers/staging/tm6000/tm6000-i2c.c Fri Apr 23 04:23:03 2010 +1000 renamed from linux/drivers/staging/tm6000/tm6000-i2c.c Mon Apr 05 22:56:43 2010 -0400 +144
-9@@ -24,6 +24,7 @@ #include <linux/kernel.h> #include <linux/usb.h> #include <linux/i2c.h> +#include <linux/delay.h> #include "compat.h" #include "tm6000.h"@@ -45,11 +46,39 @@ printk(KERN_DEBUG "%s at %s: " fmt, \ dev->name, __FUNCTION__ , ##args); } while (0) +static void tm6000_i2c_reset(struct tm6000_core *dev) +{ + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 0); + msleep(15); + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1); + msleep(15); +} + static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, __u8 reg, char *buf, int len) { - return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); + int rc; + unsigned int tsleep; + + if (!buf || len < 1 || len > 64) + return -1; + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, + addr | reg << 8, 0, buf, len); + + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len * 200) + 200 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc; } /* Generic read - doesn't work fine with 16bit registers */@@ -59,22 +88,30 @@ int rc; u8 b[2]; - if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { + if (!buf || len < 1 || len > 64) + return -1; + + /* capture mutex */ + if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) + && (reg % 2 == 0)) { /* * Workaround an I2C bug when reading from zl10353 */ reg -= 1; len += 1; - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len); + rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, + addr | reg << 8, 0, b, len); *buf = b[1]; } else { - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); + rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, + addr | reg << 8, 0, buf, len); } + /* release mutex */ return rc; }@@ -85,8 +122,106 @@ static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr, __u16 reg, char *buf, int len) { - return tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_14_SET_GET_I2C_WR2_RDN, addr, reg, buf, len); + int rc; + unsigned char ureg; + + if (!buf || len != 2) + return -1; + + /* capture mutex */ + ureg = reg & 0xFF; + rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, + addr | (reg & 0xFF00), 0, &ureg, 1); + + if (rc < 0) { + /* release mutex */ + return rc; + } + + msleep(1400 / 1000); + rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ, + reg, 0, buf, len); + + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* release mutex */ + return rc; +} + +static int tm6000_i2c_read_sequence(struct tm6000_core *dev, unsigned char addr, + __u16 reg, char *buf, int len) +{ + int rc; + + if (!buf || len < 1 || len > 64) + return -1; + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ, + reg, 0, buf, len); + /* release mutex */ + return rc; +} + +static int tm6000_i2c_write_sequence(struct tm6000_core *dev, + unsigned char addr, __u16 reg, char *buf, + int len) +{ + int rc; + unsigned int tsleep; + + if (!buf || len < 1 || len > 64) + return -1; + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, + addr | reg << 8, 0, buf+1, len-1); + + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len * 200) + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc; +} + +static int tm6000_i2c_write_uni(struct tm6000_core *dev, unsigned char addr, + __u16 reg, char *buf, int len) +{ + int rc; + unsigned int tsleep; + + if (!buf || len < 1 || len > 64) + return -1; + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_30_I2C_WRITE, + addr | reg << 8, 0, buf+1, len-1); + + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len * 200) + 1000 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc; } static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,Signed-off-by Beholder Intl. Ltd. Dmitry Belimov <[email protected]>With my best regards, Dmitry.
Hi
It's my error. This code good only for tm6010. Now I rework my patch.
With my best regards, Dmitry.
Quoted 285 lines
I am still able to watch tv after applying the patch but the return code is bad and is causing unnecessary reloading of the same firmwares.
[ 2482.599040] usb 1-1: firmware: requesting tm6000-xc3028.fw [ 2482.607229] xc2028 2-0061: Loading 77 firmware images from tm6000-xc3028.fw, type: xc2028 firmware, ver 2.4 [ 2482.788089] xc2028 2-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000. [ 2503.620069] (0), id 00000000000000ff: [ 2503.620078] xc2028 2-0061: Loading firmware for type=(0), id 0000000100000007. [ 2504.380061] xc2028 2-0061: Loading SCODE for type=MONO SCODE HAS_IF_5320 (60008000), id 0000000f00000007. [ 2504.520063] xc2028 2-0061: i2c input error: rc = -32 (should be 2) [ 2504.536064] xc2028 2-0061: Unable to read tuner registers. [ 2504.776079] xc2028 2-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000. [ 2525.556048] (0), id 00000000000000ff: [ 2525.556057] xc2028 2-0061: Loading firmware for type=(0), id 0000000100000007. [ 2526.312058] xc2028 2-0061: Loading SCODE for type=MONO SCODE HAS_IF_5320 (60008000), id 0000000f00000007. [ 2526.452061] xc2028 2-0061: i2c input error: rc = -32 (should be 2) [ 2526.468050] xc2028 2-0061: Unable to read tuner registers. [ 2527.648076] xc2028 2-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000. [ 2548.460067] (0), id 00000000000000ff: [ 2548.460076] xc2028 2-0061: Loading firmware for type=(0), id 0000000100000007. [ 2549.216070] xc2028 2-0061: Loading SCODE for type=MONO SCODE HAS_IF_5320 (60008000), id 0000000f00000007. [ 2549.356064] xc2028 2-0061: i2c input error: rc = -32 (should be 2) [ 2549.372065] xc2028 2-0061: Unable to read tuner registers. [ 2549.612052] xc2028 2-0061: Loading firmware for type=BASE F8MHZ (3), id 0000000000000000. [ 2570.609041] (0), id 00000000000000ff: [ 2570.609049] xc2028 2-0061: Loading firmware for type=(0), id 0000000100000007. [ 2571.397034] xc2028 2-0061: Loading SCODE for type=MONO SCODE HAS_IF_5320 (60008000), id 0000000f00000007. [ 2571.537025] xc2028 2-0061: i2c input error: rc = -32 (should be 2) [ 2571.553024] xc2028 2-0061: Unable to read tuner registers. [ 2572.553103] Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: 0) [ 2572.561090] tm6000: open called (dev=video0) [ 2573.081022] Original value=96 [ 2573.093037] tm6000: VIDIOC_QUERYCAP [ 2573.149565] tm6000: open called (dev=video0)Quoted 232 lines · Dmitri Belimov
Hi
Rework I2C for read word from connected devices, now it works well. Add new functions for read/write blocks.
diff -r
7c0b887911cflinux/drivers/staging/tm6000/tm6000-i2c.c---a/linux/drivers/staging/tm6000/tm6000-i2c.cMon Apr 05 22:56:43 2010 -0400 +++b/linux/drivers/staging/tm6000/tm6000-i2c.cFri Apr 23 04:23:03 2010 +1000 @@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/i2c.h>
+#include <linux/delay.h>#include "
compat.h"
#include "tm6000.h"(quoted diff) +0
-0@@ -45,11 +46,39 @@ printk(KERN_DEBUG "%s at %s: " fmt, \dev->name,
__FUNCTION__, ##args); } while
(0)linux/drivers/staging/tm6000/tm6000-i2c.c +3
-0+static void tm6000_i2c_reset (struct tm6000_core *dev) +{ + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
TM6000_GPIO_CLK, 0);
+ msleep(15);
+tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1);
+ msleep(15);(quoted diff) +2
-0+} +static int
tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, __u8 reg, char *buf, int len)
{
- return tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
-REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
+ int rc;
+ unsigned int tsleep;linux/drivers/staging/tm6000/tm6000-i2c.c +6
-0+ + if (!buf || len < 1 || len > 64) + return -1; + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf, len);linux/drivers/staging/tm6000/tm6000-i2c.c +12
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len * 200) + 200 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc;}
/* Generic read - doesn't work fine with 16bit registers */
linux/drivers/staging/tm6000/tm6000-i2c.c +7
-3@@ -59,22 +88,30 @@ int rc; u8 b[2]; - if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { + if (!buf || len < 1 || len > 64) + return -1; + + /* capture mutex */ + if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) + && (reg % 2 == 0)) { /* * Workaround an I2C bug when reading from zl10353 */ reg -= 1; len += 1; - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len); + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, b, len);*buf = b[1];
} else {
- rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
-REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
+ rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf, len);
}+ /* release mutex */
return rc;
}linux/drivers/staging/tm6000/tm6000-i2c.c +9
-2@@ -85,8 +122,106 @@ static int tm6000_i2c_recv_regs16(struct tm6000_core *dev,unsigned char addr,__u16 reg,char *buf,int len) { - return tm6000_read_write_usb(dev, USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , - REQ_14_SET_GET_I2C_WR2_RDN, addr, reg, buf, len); + int rc; + unsigned char ureg; + + if (!buf || len != 2) + return -1; + + /* capture mutex */ + ureg = reg & 0xFF; + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | (reg &0xFF00), 0, &ureg, 1);linux/drivers/staging/tm6000/tm6000-i2c.c +8
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + msleep(1400 / 1000); + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_35_AFTEK_TUNER_READ,
+ reg, 0, buf, len);linux/drivers/staging/tm6000/tm6000-i2c.c +11
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* release mutex */ + return rc; +} + +static int tm6000_i2c_read_sequence(struct tm6000_core *dev,unsigned char addr,
+__u16reg, char *buf, int len)linux/drivers/staging/tm6000/tm6000-i2c.c +8
-0+{ + int rc; + + if (!buf || len < 1 || len > 64) + return -1; + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_35_AFTEK_TUNER_READ,
+ reg, 0, buf, len);
+ /* release mutex */
+ return rc;linux/drivers/staging/tm6000/tm6000-i2c.c +4
-0+} + +static int tm6000_i2c_write_sequence (struct tm6000_core *dev, + unsigned char addr, __u16 reg, char*buf,
+ int len)linux/drivers/staging/tm6000/tm6000-i2c.c +9
-0+{ + int rc; + unsigned int tsleep; + + if (!buf || len < 1 || len > 64) + return -1; + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf+1, len-1);linux/drivers/staging/tm6000/tm6000-i2c.c +15
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len * 200) + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc; +} + +static int tm6000_i2c_write_uni(struct tm6000_core *dev, unsignedchar addr,
+__u16reg, char *buf, int len)linux/drivers/staging/tm6000/tm6000-i2c.c +9
-0+{ + int rc; + unsigned int tsleep; + + if (!buf || len < 1 || len > 64) + return -1; + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_30_I2C_WRITE,
+ addr | reg << 8, 0, buf+1, len-1);linux/drivers/staging/tm6000/tm6000-i2c.c +12
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len * 200) + 1000 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc;}
static int tm6000_i2c_xfer(struct
i2c_adapter*i2c_adap,Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov
<[email protected]>With my best regards, Dmitry.
Am 23.04.2010 02:48, schrieb Dmitri Belimov:
Quoted 113 lines
Hi
Rework I2C for read word from connected devices, now it works well. Add new functions for read/write blocks.
diff -r
7c0b887911cflinux/drivers/staging/tm6000/tm6000-i2c.clinux/drivers/staging/tm6000/tm6000-i2c.c +57
-9@@ -24,6 +24,7 @@#include <linux/kernel.h> #include <linux/usb.h> #include <linux/i2c.h> +#include <linux/delay.h> #include "compat.h" #include "tm6000.h" @@ -45,11 +46,39 @@printk (KERN_DEBUG "%s at %s: " fmt, \ dev->name, __FUNCTION__ , ##args); } while (0) +static void tm6000_i2c_reset(struct tm6000_core *dev) +{ +tm6000_set_reg (dev,REQ_03_SET_GET_MCU_PIN ,TM6000_GPIO_CLK ,0 ); +msleep (15 ); +tm6000_set_reg (dev,REQ_03_SET_GET_MCU_PIN ,TM6000_GPIO_CLK ,1 ); +msleep (15 ); +} +static int tm6000_i2c_send_regs (struct tm6000_core *dev,unsigned char addr,__u8 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , buf, len); +int rc; +unsigned int tsleep; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf, len); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len *200 ) +200 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; }/* Generic read - doesn't work fine with 16bit registers */ @@ -59,22 +88,30 @@int rc;u8 b[2 ]; -if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) && (reg %2 ==0 )) { +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ +if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) + && (reg %2 ==0 )) {/* * Workaround an I2C bug when reading from zl10353 */ reg -=1 ; len +=1 ; - rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , b, len); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , b, len); *buf = b[1 ]; }else { - rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , buf, len); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf, len); } +/* release mutex */ return rc; }@@ -85,8 +122,106 @@static int tm6000_i2c_recv_regs16 (struct tm6000_core *dev,unsigned char addr,__u16 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_14_SET_GET_I2C_WR2_RDN , addr, reg, buf, len); +int rc; +unsigned char ureg; + +if (!buf || len !=2 ) +return -1 ; + +/* capture mutex */ + ureg = reg &0xFF ; + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | (reg &0xFF00 ),0 , &ureg,1 ); + +if (rc <0 ) {
linux/drivers/staging/tm6000/tm6000-i2c.c line 147
Quoted 10 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +9
-0+/* release mutex */ +return rc; + } + +msleep (1400 /1000 ); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_35_AFTEK_TUNER_READ , + reg,0 , buf, len); +
not all can this request (chip revision 0xf3 and 0xf4 can it)
Quoted 12 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +12
-0+if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* release mutex */ +return rc; +} + +static int tm6000_i2c_read_sequence (struct tm6000_core *dev,unsigned char addr, +__u16 reg,char *buf,int len) +{
linux/drivers/staging/tm6000/tm6000-i2c.c line 226
Quoted 10 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +9
-0+int rc; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_35_AFTEK_TUNER_READ , + reg,0 , buf, len);
ditto
Quoted 65 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +57
-0+/* release mutex */ +return rc; +} + +static int tm6000_i2c_write_sequence (struct tm6000_core *dev, +unsigned char addr,__u16 reg,char *buf, +int len) +{ +int rc; +unsigned int tsleep; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf+1 , len-1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len *200 ) +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; +} + +static int tm6000_i2c_write_uni (struct tm6000_core *dev,unsigned char addr, +__u16 reg,char *buf,int len) +{ +int rc; +unsigned int tsleep; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_30_I2C_WRITE , + addr | reg <<8 ,0 , buf+1 , len-1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len *200 ) +1000 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; }static int tm6000_i2c_xfer(struct
i2c_adapter*i2c_adap,Signed-off-by Beholder Intl. Ltd. Dmitry Belimov <[email protected]>With my best regards, Dmitry.
Signature · 1 line
Stefan Ringel <[email protected]>
Hi
It's my error. This code good only for tm6010. Now I rework my patch.
With my best regards, Dmitry.
Quoted 241 lines
Am 23.04.2010 02:48, schrieb Dmitri Belimov:
Quoted 136 lines
Hi
Rework I2C for read word from connected devices, now it works well. Add new functions for read/write blocks.
diff -r
7c0b887911cflinux/drivers/staging/tm6000/tm6000-i2c.c
---a/linux/drivers/staging/tm6000/tm6000-i2c.cMon Apr 05
22:56:43 2010 -0400 +++b/linux/drivers/staging/tm6000/tm6000-i2c.cFri Apr 23
04:23:03 2010 +1000 @@ -24,6 +24,7 @@ #include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/i2c.h>linux/drivers/staging/tm6000/tm6000-i2c.c +9
-2+#include <linux/delay.h> #include "compat.h" #include "tm6000.h" @@ -45,11 +46,39 @@printk (KERN_DEBUG "%s at %s: " fmt, \ dev->name, __FUNCTION__ , ##args); } while (0 ) +static void tm6000_i2c_reset(struct tm6000_core *dev) +{ +tm6000_set_reg (dev,REQ_03_SET_GET_MCU_PIN ,TM6000_GPIO_CLK ,0 ); +msleep (15 ); +tm6000_set_reg (dev,REQ_03_SET_GET_MCU_PIN ,TM6000_GPIO_CLK ,1 ); +msleep (15 ); +} +static int tm6000_i2c_send_regs (struct tm6000_core *dev,unsigned char addr,__u8 reg,char *buf,int len) { - return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0,buf, len);
linux/drivers/staging/tm6000/tm6000-i2c.c +8
-0+int rc; +unsigned int tsleep; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|linux/drivers/staging/tm6000/tm6000-i2c.c +21
-3+USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg << 8, 0, buf, len); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len *200 ) +200 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; }/* Generic read - doesn't work fine with 16bit registers */ @@ -59,22 +88,30 @@int rc;u8 b[2 ]; -if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) && (reg % 2 == 0)) { +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ +if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) + && (reg %2 ==0 )) {/* * Workaround an I2C bug when reading from zl10353 */ reg -=1 ; len +=1 ; - rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg << 8, 0, b, len); + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|linux/drivers/staging/tm6000/tm6000-i2c.c +2
-1+USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg << 8, 0, b, len); *buf = b[1 ]; }else { - rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|USB_RECIP_DEVICE,(quoted diff) +0
-1- REQ_16_SET_GET_I2C_WR1_RDN, addr | reg <<8, 0, buf, len);
(quoted diff) +1
-0+ rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|linux/drivers/staging/tm6000/tm6000-i2c.c +12
-2+USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg << 8, 0, buf, len); } +/* release mutex */ return rc; }@@ -85,8 +122,106 @@static int tm6000_i2c_recv_regs16 (struct tm6000_core *dev,unsigned char addr,__u16 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_14_SET_GET_I2C_WR2_RDN , addr, reg, buf, len); + int rc; +unsigned char ureg; + +if (!buf || len !=2 ) +return -1 ; + +/* capture mutex */ + ureg = reg &0xFF ; + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|linux/drivers/staging/tm6000/tm6000-i2c.c +10
-0+USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | (reg & 0xFF00), 0, &ureg, 1); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +msleep (1400 /1000 ); + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|linux/drivers/staging/tm6000/tm6000-i2c.c line 146
Quoted 3 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +3
-0+USB_RECIP_DEVICE ,REQ_35_AFTEK_TUNER_READ , + reg, 0, buf, len); +not all can this request (chip revision
0xf3and0xf4can it)Quoted 22 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +10
-0+if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* release mutex */ +return rc; +} + +static int tm6000_i2c_read_sequence(struct tm6000_core *dev,unsigned char addr,
linux/drivers/staging/tm6000/tm6000-i2c.c +9
-0+ __u16 reg, char *buf, int len) +{ + int rc; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|Review
Quoted 2 lines
(quoted diff) +2
-0+ USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ, + reg, 0, buf, len);ditto
Quoted 70 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +6
-0+/* release mutex */ +return rc; +} + +static int tm6000_i2c_write_sequence(struct tm6000_core *dev, + unsigned char addr, __u16 reg,char *buf,
linux/drivers/staging/tm6000/tm6000-i2c.c +10
-0+ int len) +{ +int rc; +unsigned int tsleep; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|linux/drivers/staging/tm6000/tm6000-i2c.c +17
-0+USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg << 8, 0, buf+1, len-1); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len *200 ) +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; +} + +static int tm6000_i2c_write_uni(struct tm6000_core *dev, unsignedchar addr,
linux/drivers/staging/tm6000/tm6000-i2c.c +10
-0+ __u16 reg, char *buf, int len) +{ + int rc; +unsigned int tsleep; + +if (!buf || len <1 || len >64 ) +return -1 ; + +/* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|linux/drivers/staging/tm6000/tm6000-i2c.c +14
-0+USB_RECIP_DEVICE ,REQ_30_I2C_WRITE , + addr | reg << 8, 0, buf+1, len-1); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len *200 ) +1000 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; } static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov
<[email protected]>With my best regards, Dmitry.
Signature · 1 line
Stefan Ringel <[email protected]>
Hi
Rework last I2C patch.
Set correct limit for I2C packet.
Use different method for the tm5600/tm6000 and tm6010 to read word.
Try this patch.
linux/drivers/staging/tm6000/tm6000-i2c.c +195 -9
@@ -24,6 +24,7 @@#include <linux/kernel.h> #include <linux/usb.h> #include <linux/i2c.h> +#include <linux/delay.h> #include "compat.h" #include "tm6000.h"
@@ -45,11 +46,49 @@printk (KERN_DEBUG "%s at %s: " fmt, \ dev->name, __FUNCTION__ , ##args); } while (0) +static void tm6000_i2c_reset(struct tm6000_core *dev) +{ +tm6000_set_reg (dev,REQ_03_SET_GET_MCU_PIN ,TM6000_GPIO_CLK ,0 ); +msleep (15 ); +tm6000_set_reg (dev,REQ_03_SET_GET_MCU_PIN ,TM6000_GPIO_CLK ,1 ); +msleep (15 ); +} +static int tm6000_i2c_send_regs (struct tm6000_core *dev,unsigned char addr,__u8 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , buf, len); +int rc; +unsigned int tsleep; +unsigned int i2c_packet_limit =16 ; + +if (dev->dev_type ==TM6010 ) + i2c_packet_limit =64 ; + +if (!buf) +return -1 ; + +if (len <1 || len > i2c_packet_limit){ +printk ("Incorrect lenght of i2c packet = %d, limit set to %d\n" , + len, i2c_packet_limit); +return -1 ; + } + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf, len); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len *200 ) +200 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; }/* Generic read - doesn't work fine with 16bit registers */
@@ -58,23 +97,41 @@ {int rc;u8 b[2 ]; +unsigned int i2c_packet_limit =16 ; -if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) && (reg %2 ==0 )) { +if (dev->dev_type ==TM6010 ) + i2c_packet_limit =64 ; + +if (!buf) +return -1 ; + +if (len <1 || len > i2c_packet_limit){ +printk ("Incorrect lenght of i2c packet = %d, limit set to %d\n" , + len, i2c_packet_limit); +return -1 ; + } + +/* capture mutex */ +if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) + && (reg %2 ==0 )) {/* * Workaround an I2C bug when reading from zl10353 */ reg -=1 ; len +=1 ; - rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , b, len); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , b, len); *buf = b[1 ]; }else { - rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , buf, len); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf, len); } +/* release mutex */ return rc; }
@@ -85,8 +142,137 @@static int tm6000_i2c_recv_regs16 (struct tm6000_core *dev,unsigned char addr,__u16 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_14_SET_GET_I2C_WR2_RDN , addr, reg, buf, len); +int rc; +unsigned char ureg; + +if (!buf || len !=2 ) +return -1 ; + +/* capture mutex */ +if (dev->dev_type ==TM6010 ){ + ureg = reg &0xFF ; + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | (reg &0xFF00 ),0 , &ureg,1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +msleep (1400 /1000 ); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_35_AFTEK_TUNER_READ , + reg,0 , buf, len); + } +else { + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_14_SET_GET_I2C_WR2_RDN , + addr, reg, buf, len); + } + +/* release mutex */ +return rc; +} + +static int tm6000_i2c_read_sequence (struct tm6000_core *dev,unsigned char addr, +__u16 reg,char *buf,int len) +{ +int rc; + +if (dev->dev_type !=TM6010 ) +return -1 ; + +if (!buf) +return -1 ; + +if (len <1 || len >64 ){ +printk ("Incorrect lenght of i2c packet = %d, limit set to 64\n" , + len); +return -1 ; + } + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_35_AFTEK_TUNER_READ , + reg,0 , buf, len); +/* release mutex */ +return rc; +} + +static int tm6000_i2c_write_sequence (struct tm6000_core *dev, +unsigned char addr,__u16 reg,char *buf, +int len) +{ +int rc; +unsigned int tsleep; +unsigned int i2c_packet_limit =16 ; + +if (dev->dev_type ==TM6010 ) + i2c_packet_limit =64 ; + +if (!buf) +return -1 ; + +if (len <1 || len > i2c_packet_limit){ +printk ("Incorrect lenght of i2c packet = %d, limit set to %d\n" , + len, i2c_packet_limit); +return -1 ; + } + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf+1 , len-1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len *200 ) +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; +} + +static int tm6000_i2c_write_uni (struct tm6000_core *dev,unsigned char addr, +__u16 reg,char *buf,int len) +{ +int rc; +unsigned int tsleep; +unsigned int i2c_packet_limit =16 ; + +if (dev->dev_type ==TM6010 ) + i2c_packet_limit =64 ; + +if (!buf) +return -1 ; + +if (len <1 || len > i2c_packet_limit){ +printk ("Incorrect lenght of i2c packet = %d, limit set to %d\n" , + len, i2c_packet_limit); +return -1 ; + } + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_30_I2C_WRITE , + addr | reg <<8 ,0 , buf+1 , len-1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len *200 ) +1000 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; } static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
With my best regards, Dmitry.
linux/drivers/staging/tm6000/tm6000-i2c.c +195 -9
243 lines not on this page · raw message
thanks. This is work fine on my tm5600.
btw, can you use the git tree? There is some codes update from Stefan there for the tm6000-i2c that is still not sync with hg.
Quoted 261 lines · Dmitri Belimov
Hi
Rework last I2C patch.
Set correct limit for I2C packet.
Use different method for the tm5600/tm6000 and tm6010 to read word.Try this patch.
diff -r
7c0b887911cflinux/drivers/staging/tm6000/tm6000-i2c.clinux/drivers/staging/tm6000/tm6000-i2c.c Mon Apr 26 04:15:56 2010 +1000 renamed from linux/drivers/staging/tm6000/tm6000-i2c.c Mon Apr 05 22:56:43 2010 -0400 +195
-9@@ -24,6 +24,7 @@ #include <linux/kernel.h> #include <linux/usb.h> #include <linux/i2c.h> +#include <linux/delay.h> #include "compat.h" #include "tm6000.h"@@ -45,11 +46,49 @@ printk(KERN_DEBUG "%s at %s: " fmt, \ dev->name, __FUNCTION__ , ##args); } while (0) +static void tm6000_i2c_reset(struct tm6000_core *dev) +{ + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 0); + msleep(15); + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1); + msleep(15); +} + static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, __u8 reg, char *buf, int len) { - return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); + int rc; + unsigned int tsleep; + unsigned int i2c_packet_limit = 16; + + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limit set to %d\n", + len, i2c_packet_limit); + return -1; + } + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, + addr | reg << 8, 0, buf, len); + + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len * 200) + 200 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc; } /* Generic read - doesn't work fine with 16bit registers */@@ -58,23 +97,41 @@ { int rc; u8 b[2]; + unsigned int i2c_packet_limit = 16; - if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limit set to %d\n", + len, i2c_packet_limit); + return -1; + } + + /* capture mutex */ + if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) + && (reg % 2 == 0)) { /* * Workaround an I2C bug when reading from zl10353 */ reg -= 1; len += 1; - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len); + rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, + addr | reg << 8, 0, b, len); *buf = b[1]; } else { - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); + rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, + addr | reg << 8, 0, buf, len); } + /* release mutex */ return rc; }@@ -85,8 +142,137 @@ static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr, __u16 reg, char *buf, int len) { - return tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_14_SET_GET_I2C_WR2_RDN, addr, reg, buf, len); + int rc; + unsigned char ureg; + + if (!buf || len != 2) + return -1; + + /* capture mutex */ + if (dev->dev_type == TM6010){ + ureg = reg & 0xFF; + rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, + addr | (reg & 0xFF00), 0, &ureg, 1); + + if (rc < 0) { + /* release mutex */ + return rc; + } + + msleep(1400 / 1000); + rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ, + reg, 0, buf, len); + } + else { + rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_14_SET_GET_I2C_WR2_RDN, + addr, reg, buf, len); + } + + /* release mutex */ + return rc; +} + +static int tm6000_i2c_read_sequence(struct tm6000_core *dev, unsigned char addr, + __u16 reg, char *buf, int len) +{ + int rc; + + if (dev->dev_type != TM6010) + return -1; + + if (!buf) + return -1; + + if (len < 1 || len > 64){ + printk("Incorrect lenght of i2c packet = %d, limit set to 64\n", + len); + return -1; + } + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ, + reg, 0, buf, len); + /* release mutex */ + return rc; +} + +static int tm6000_i2c_write_sequence(struct tm6000_core *dev, + unsigned char addr, __u16 reg, char *buf, + int len) +{ + int rc; + unsigned int tsleep; + unsigned int i2c_packet_limit = 16; + + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limit set to %d\n", + len, i2c_packet_limit); + return -1; + } + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, + addr | reg << 8, 0, buf+1, len-1); + + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len * 200) + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc; +} + +static int tm6000_i2c_write_uni(struct tm6000_core *dev, unsigned char addr, + __u16 reg, char *buf, int len) +{ + int rc; + unsigned int tsleep; + unsigned int i2c_packet_limit = 16; + + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limit set to %d\n", + len, i2c_packet_limit); + return -1; + } + + /* capture mutex */ + rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, REQ_30_I2C_WRITE, + addr | reg << 8, 0, buf+1, len-1); + + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len * 200) + 1000 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc; } static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,With my best regards, Dmitry.
Quoted 1 line · On Mon, 26 Apr 2010 20:58:24 +0800 Bee Hock Goh <[email protected]> wrote:
thanks. This is work fine on my tm5600.
Good news.
Quoted 2 lines
btw, can you use the git tree? There is some codes update from Stefan there for the tm6000-i2c that is still not sync with hg.
no problemm. Give me access and URL.
With my best regards, Dmitry.
Quoted 294 lines
Quoted 292 lines · Dmitri Belimov
Hi
Rework last I2C patch.
Set correct limit for I2C packet.
Use different method for the tm5600/tm6000 and tm6010 to read word.Try this patch.
diff -r
7c0b887911cflinux/drivers/staging/tm6000/tm6000-i2c.c---a/linux/drivers/staging/tm6000/tm6000-i2c.cMon Apr 05 22:56:43 2010 -0400 +++b/linux/drivers/staging/tm6000/tm6000-i2c.cMon Apr 26 04:15:56 2010 +1000 @@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/i2c.h>
+#include <linux/delay.h>#include "
compat.h"
#include "tm6000.h"(quoted diff) +0
-0@@ -45,11 +46,49 @@ printk(KERN_DEBUG "%s at %s: " fmt, \dev->name,
__FUNCTION__, ##args); } while
(0)linux/drivers/staging/tm6000/tm6000-i2c.c +3
-0+static void tm6000_i2c_reset (struct tm6000_core *dev) +{ + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
TM6000_GPIO_CLK, 0);
+ msleep(15);
+tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1);
+ msleep(15);(quoted diff) +2
-0+} +static int
tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, __u8 reg, char *buf, int len)
{
- return tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
-REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
+ int rc;
+ unsigned int tsleep;
+ unsigned inti2c_packet_limit= 16;linux/drivers/staging/tm6000/tm6000-i2c.c +9
-0+ + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limitset to %d\n",
+ len,i2c_packet_limit);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf, len);linux/drivers/staging/tm6000/tm6000-i2c.c +12
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len * 200) + 200 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc;}
/* Generic read - doesn't work fine with 16bit registers */
linux/drivers/staging/tm6000/tm6000-i2c.c +17
-3@@ -58,23 +97,41 @@ { int rc; u8 b[2]; + unsigned int i2c_packet_limit = 16; - if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limit set to %d\n", + len, i2c_packet_limit); + return -1; + } + + /* capture mutex */ + if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) + && (reg % 2 == 0)) { /* * Workaround an I2C bug when reading from zl10353 */ reg -= 1; len += 1; - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len); + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, b, len);*buf = b[1];
} else {
- rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
-REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
+ rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf, len);
}+ /* release mutex */
return rc;
}linux/drivers/staging/tm6000/tm6000-i2c.c +10
-2@@ -85,8 +142,137 @@ static int tm6000_i2c_recv_regs16(struct tm6000_core *dev,unsigned char addr,__u16 reg,char *buf,int len) { - return tm6000_read_write_usb(dev, USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , - REQ_14_SET_GET_I2C_WR2_RDN, addr, reg, buf, len); + int rc; + unsigned char ureg; + + if (!buf || len != 2) + return -1; + + /* capture mutex */ + if (dev->dev_type == TM6010){ + ureg = reg & 0xFF; + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | (reg &0xFF00), 0, &ureg, 1);linux/drivers/staging/tm6000/tm6000-i2c.c +8
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + msleep(1400 / 1000); + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_35_AFTEK_TUNER_READ,
+ reg, 0, buf, len);
+ }
+ else {
+ rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_14_SET_GET_I2C_WR2_RDN,
+ addr, reg, buf, len);
+ }linux/drivers/staging/tm6000/tm6000-i2c.c +6
-0+ + /* release mutex */ + return rc; +} + +static int tm6000_i2c_read_sequence(struct tm6000_core *dev,unsigned char addr,
+__u16reg, char *buf, int len)linux/drivers/staging/tm6000/tm6000-i2c.c +11
-0+{ + int rc; + + if (dev->dev_type != TM6010) + return -1; + + if (!buf) + return -1; + + if (len < 1 || len > 64){ + printk("Incorrect lenght of i2c packet = %d, limitset to 64\n",
+ len);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_35_AFTEK_TUNER_READ,
+ reg, 0, buf, len);
+ /* release mutex */
+ return rc;linux/drivers/staging/tm6000/tm6000-i2c.c +4
-0+} + +static int tm6000_i2c_write_sequence (struct tm6000_core *dev, + unsigned char addr, __u16 reg, char*buf,
+ int len)linux/drivers/staging/tm6000/tm6000-i2c.c +13
-0+{ + int rc; + unsigned int tsleep; + unsigned int i2c_packet_limit = 16; + + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limitset to %d\n",
+ len,i2c_packet_limit);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf+1, len-1);linux/drivers/staging/tm6000/tm6000-i2c.c +15
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len * 200) + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc; +} + +static int tm6000_i2c_write_uni(struct tm6000_core *dev, unsignedchar addr,
+__u16reg, char *buf, int len)linux/drivers/staging/tm6000/tm6000-i2c.c +13
-0+{ + int rc; + unsigned int tsleep; + unsigned int i2c_packet_limit = 16; + + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limitset to %d\n",
+ len,i2c_packet_limit);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_30_I2C_WRITE,
+ addr | reg << 8, 0, buf+1, len-1);linux/drivers/staging/tm6000/tm6000-i2c.c +12
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len * 200) + 1000 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc;}
static int tm6000_i2c_xfer(struct
i2c_adapter*i2c_adap,With my best regards, Dmitry.
wiki is your best friend. :)
http://www.linuxtv.org/wiki/index.php/Maintaining_Git_trees
http://www.linuxtv.org/wiki/index.php/Using_a_git_driver_development_tree
Quoted 309 lines · Dmitri Belimov
Quoted 1 line · On Mon, 26 Apr 2010 20:58:24 +0800 Bee Hock Goh <[email protected]> wrote:
thanks. This is work fine on my tm5600.
Good news.
Quoted 2 lines
btw, can you use the git tree? There is some codes update from Stefan there for the tm6000-i2c that is still not sync with hg.
no problemm. Give me access and URL.
With my best regards, Dmitry.
Quoted 294 lines
Quoted 292 lines · Dmitri Belimov
Hi
Rework last I2C patch.
Set correct limit for I2C packet.
Use different method for the tm5600/tm6000 and tm6010 to read word.Try this patch.
diff -r
7c0b887911cflinux/drivers/staging/tm6000/tm6000-i2c.c---a/linux/drivers/staging/tm6000/tm6000-i2c.cMon Apr 05 22:56:43 2010 -0400 +++b/linux/drivers/staging/tm6000/tm6000-i2c.cMon Apr 26 04:15:56 2010 +1000 @@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/i2c.h>
+#include <linux/delay.h>#include "
compat.h"
#include "tm6000.h"(quoted diff) +0
-0@@ -45,11 +46,49 @@ printk(KERN_DEBUG "%s at %s: " fmt, \dev->name,
__FUNCTION__, ##args); } while
(0)linux/drivers/staging/tm6000/tm6000-i2c.c +3
-0+static void tm6000_i2c_reset (struct tm6000_core *dev) +{ + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
TM6000_GPIO_CLK, 0);
+ msleep(15);
+tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1);
+ msleep(15);(quoted diff) +2
-0+} +static int
tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, __u8 reg, char *buf, int len)
{
- return tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
-REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
+ int rc;
+ unsigned int tsleep;
+ unsigned inti2c_packet_limit= 16;linux/drivers/staging/tm6000/tm6000-i2c.c +9
-0+ + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limitset to %d\n",
+ len,i2c_packet_limit);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf, len);linux/drivers/staging/tm6000/tm6000-i2c.c +12
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len * 200) + 200 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc;}
/* Generic read - doesn't work fine with 16bit registers */
linux/drivers/staging/tm6000/tm6000-i2c.c +17
-3@@ -58,23 +97,41 @@ { int rc; u8 b[2]; + unsigned int i2c_packet_limit = 16; - if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limit set to %d\n", + len, i2c_packet_limit); + return -1; + } + + /* capture mutex */ + if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) + && (reg % 2 == 0)) { /* * Workaround an I2C bug when reading from zl10353 */ reg -= 1; len += 1; - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len); + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, b, len);*buf = b[1];
} else {
- rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
-REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
+ rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf, len);
}+ /* release mutex */
return rc;
}linux/drivers/staging/tm6000/tm6000-i2c.c +10
-2@@ -85,8 +142,137 @@ static int tm6000_i2c_recv_regs16(struct tm6000_core *dev,unsigned char addr,__u16 reg,char *buf,int len) { - return tm6000_read_write_usb(dev, USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , - REQ_14_SET_GET_I2C_WR2_RDN, addr, reg, buf, len); + int rc; + unsigned char ureg; + + if (!buf || len != 2) + return -1; + + /* capture mutex */ + if (dev->dev_type == TM6010){ + ureg = reg & 0xFF; + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | (reg &0xFF00), 0, &ureg, 1);linux/drivers/staging/tm6000/tm6000-i2c.c +8
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + msleep(1400 / 1000); + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_35_AFTEK_TUNER_READ,
+ reg, 0, buf, len);
+ }
+ else {
+ rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_14_SET_GET_I2C_WR2_RDN,
+ addr, reg, buf, len);
+ }linux/drivers/staging/tm6000/tm6000-i2c.c +6
-0+ + /* release mutex */ + return rc; +} + +static int tm6000_i2c_read_sequence(struct tm6000_core *dev,unsigned char addr,
+__u16reg, char *buf, int len)linux/drivers/staging/tm6000/tm6000-i2c.c +11
-0+{ + int rc; + + if (dev->dev_type != TM6010) + return -1; + + if (!buf) + return -1; + + if (len < 1 || len > 64){ + printk("Incorrect lenght of i2c packet = %d, limitset to 64\n",
+ len);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_35_AFTEK_TUNER_READ,
+ reg, 0, buf, len);
+ /* release mutex */
+ return rc;linux/drivers/staging/tm6000/tm6000-i2c.c +4
-0+} + +static int tm6000_i2c_write_sequence (struct tm6000_core *dev, + unsigned char addr, __u16 reg, char*buf,
+ int len)linux/drivers/staging/tm6000/tm6000-i2c.c +13
-0+{ + int rc; + unsigned int tsleep; + unsigned int i2c_packet_limit = 16; + + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limitset to %d\n",
+ len,i2c_packet_limit);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf+1, len-1);linux/drivers/staging/tm6000/tm6000-i2c.c +15
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len * 200) + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc; +} + +static int tm6000_i2c_write_uni(struct tm6000_core *dev, unsignedchar addr,
+__u16reg, char *buf, int len)linux/drivers/staging/tm6000/tm6000-i2c.c +13
-0+{ + int rc; + unsigned int tsleep; + unsigned int i2c_packet_limit = 16; + + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limitset to %d\n",
+ len,i2c_packet_limit);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_30_I2C_WRITE,
+ addr | reg << 8, 0, buf+1, len-1);linux/drivers/staging/tm6000/tm6000-i2c.c +12
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len * 200) + 1000 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc;}
static int tm6000_i2c_xfer(struct
i2c_adapter*i2c_adap,With my best regards, Dmitry.
Quoted 4 lines · On Tue, 27 Apr 2010 14:07:00 +0800 Bee Hock Goh <[email protected]> wrote:
wiki is your best friend. :)
http://www.linuxtv.org/wiki/index.php/Maintaining_Git_trees
http://www.linuxtv.org/wiki/index.php/Using_a_git_driver_development_tree
Ok.
This is new version. Made by git.
drivers/staging/tm6000/tm6000-i2c.c +78 -4
@@ -47,8 +47,38 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");static int tm6000_i2c_send_regs (struct tm6000_core *dev,unsigned char addr,__u8 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , buf, len); +int rc; +unsigned int tsleep; +unsigned int i2c_packet_limit =16 ; + +if (dev->dev_type ==TM6010 ) + i2c_packet_limit =64 ; + +if (!buf) +return -1 ; + +if (len <1 || len > i2c_packet_limit){ +printk ("Incorrect lenght of i2c packet = %d, limit set to %d\n" , + len, i2c_packet_limit); +return -1 ; + } + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf, len); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len *200 ) +200 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; }/* Generic read - doesn't work fine with 16bit registers */
@@ -57,7 +87,21 @@ static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr, {int rc;u8 b[2 ]; +unsigned int i2c_packet_limit =16 ; + +if (dev->dev_type ==TM6010 ) + i2c_packet_limit =64 ; + +if (!buf) +return -1 ; +if (len <1 || len > i2c_packet_limit){ +printk ("Incorrect lenght of i2c packet = %d, limit set to %d\n" , + len, i2c_packet_limit); +return -1 ; + } + +/* capture mutex */ if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) && (reg %2 ==0 )) {/* * Workaround an I2C bug when reading from zl10353
@@ -74,6 +118,7 @@ static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr, REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); } +/* release mutex */ return rc; }
@@ -84,8 +129,37 @@ static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr,static int tm6000_i2c_recv_regs16 (struct tm6000_core *dev,unsigned char addr,__u16 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_14_SET_GET_I2C_WR2_RDN , addr, reg, buf, len); +int rc; +unsigned char ureg; + +if (!buf || len !=2 ) +return -1 ; + +/* capture mutex */ +if (dev->dev_type ==TM6010 ){ + ureg = reg &0xFF ; + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | (reg &0xFF00 ),0 , &ureg,1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +msleep (1400 /1000 ); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_35_AFTEK_TUNER_READ , + reg,0 , buf, len); + } +else { + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_14_SET_GET_I2C_WR2_RDN , + addr, reg, buf, len); + } + +/* release mutex */ +return rc; } static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
Quoted 309 lines
Quoted 306 lines · Dmitri Belimov
Quoted 1 line · On Mon, 26 Apr 2010 20:58:24 +0800 Bee Hock Goh <[email protected]> wrote:
thanks. This is work fine on my tm5600.
Good news.
Quoted 2 lines
btw, can you use the git tree? There is some codes update from Stefan there for the tm6000-i2c that is still not sync with hg.
no problemm. Give me access and URL.
With my best regards, Dmitry.
Quoted 292 lines
Quoted 290 lines · Dmitri Belimov
Hi
Rework last I2C patch.
Set correct limit for I2C packet.
Use different method for the tm5600/tm6000 and tm6010 to read word.Try this patch.
diff -r
7c0b887911cflinux/drivers/staging/tm6000/tm6000-i2c.c---a/linux/drivers/staging/tm6000/tm6000-i2c.cMon Apr 05 22:56:43 2010 -0400 +++b/linux/drivers/staging/tm6000/tm6000-i2c.cMon Apr 26 04:15:56 2010 +1000 @@ -24,6 +24,7 @@ #include <linux/kernel.h> #include <linux/usb.h>
#include <linux/i2c.h>
+#include <linux/delay.h>#include "
compat.h"
#include "tm6000.h"(quoted diff) +0
-0@@ -45,11 +46,49 @@ printk(KERN_DEBUG "%s at %s: " fmt, \dev->name,
__FUNCTION__, ##args); } while
(0)(quoted diff) +3
-0+static void tm6000_i2c_reset(struct tm6000_core *dev) +{ + tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
TM6000_GPIO_CLK, 0);
+ msleep(15);
+tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1);
+ msleep(15);(quoted diff) +2
-0+} +static int
tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, __u8 reg, char *buf, int len)
{
- return tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
-REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
+ int rc;
+ unsigned int tsleep;
+ unsigned inti2c_packet_limit= 16;(quoted diff) +9
-0+ + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d,limit set to %d\n",
+ len,i2c_packet_limit);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf, len);(quoted diff) +12
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len * 200) + 200 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc;}
/* Generic read - doesn't work fine with 16bit registers */
(quoted diff) +17
-3@@ -58,23 +97,41 @@ { int rc; u8 b[2]; + unsigned int i2c_packet_limit = 16; - if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d, limit set to %d\n", + len, i2c_packet_limit); + return -1; + } + + /* capture mutex */ + if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) + && (reg % 2 == 0)) { /* * Workaround an I2C bug when reading from zl10353 */ reg -= 1; len += 1; - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len); + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, b, len);*buf = b[1];
} else {
- rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE,
-REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
+ rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf, len);
}+ /* release mutex */
return rc;
}(quoted diff) +10
-2@@ -85,8 +142,137 @@ static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr, __u16 reg, char *buf, int len) { - return tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_14_SET_GET_I2C_WR2_RDN, addr, reg, buf, len); + int rc; + unsigned char ureg; + + if (!buf || len != 2) + return -1; + + /* capture mutex */ + if (dev->dev_type == TM6010){ + ureg = reg & 0xFF; + rc = tm6000_read_write_usb(dev, USB_DIR_OUT |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | (reg &0xFF00), 0, &ureg, 1);(quoted diff) +8
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + msleep(1400 / 1000); + rc = tm6000_read_write_usb(dev, USB_DIR_IN |
USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_35_AFTEK_TUNER_READ,
+ reg, 0, buf, len);
+ }
+ else {
+ rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_14_SET_GET_I2C_WR2_RDN,
+ addr, reg, buf, len);
+ }(quoted diff) +6
-0+ + /* release mutex */ + return rc; +} + +static int tm6000_i2c_read_sequence(struct tm6000_core *dev,unsigned char addr,
+__u16reg, char *buf, int len)(quoted diff) +11
-0+{ + int rc; + + if (dev->dev_type != TM6010) + return -1; + + if (!buf) + return -1; + + if (len < 1 || len > 64){ + printk("Incorrect lenght of i2c packet = %d,limit set to 64\n",
+ len);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_IN|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_35_AFTEK_TUNER_READ,
+ reg, 0, buf, len);
+ /* release mutex */
+ return rc;(quoted diff) +4
-0+} + +static int tm6000_i2c_write_sequence(struct tm6000_core *dev, + unsigned char addr, __u16 reg,char *buf,
+ int len)(quoted diff) +13
-0+{ + int rc; + unsigned int tsleep; + unsigned int i2c_packet_limit = 16; + + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d,limit set to %d\n",
+ len,i2c_packet_limit);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_16_SET_GET_I2C_WR1_RDN,
+ addr | reg << 8, 0, buf+1, len-1);(quoted diff) +15
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len * 200) + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc; +} + +static int tm6000_i2c_write_uni(struct tm6000_core *dev,unsigned char addr,
+__u16reg, char *buf, int len)(quoted diff) +13
-0+{ + int rc; + unsigned int tsleep; + unsigned int i2c_packet_limit = 16; + + if (dev->dev_type == TM6010) + i2c_packet_limit = 64; + + if (!buf) + return -1; + + if (len < 1 || len > i2c_packet_limit){ + printk("Incorrect lenght of i2c packet = %d,limit set to %d\n",
+ len,i2c_packet_limit);
+ return -1;
+ }
+
+ /* capture mutex */
+ rc = tm6000_read_write_usb(dev,USB_DIR_OUT|USB_TYPE_VENDOR|
+USB_RECIP_DEVICE,REQ_30_I2C_WRITE,
+ addr | reg << 8, 0, buf+1, len-1);(quoted diff) +12
-0+ + if (rc < 0) { + /* release mutex */ + return rc; + } + + /* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len * 200) + 1000 + 1000) / 1000; + msleep(tsleep); + + /* release mutex */ + return rc;}
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Quoted 4 lines
static int tm6000_i2c_xfer(struct
i2c_adapter*i2c_adap,With my best regards, Dmitry.
With my best regards, Dmitry.
drivers/staging/tm6000/tm6000-i2c.c +78 -4
107 lines not on this page · raw message
tm6000
In reply to Bee Hock GohHi
Anyone can watch TV with tm6000 module??
I try mplayer. My PC crashed inside copy_streams function after some time.
With my best regards, Dmitry.
Re: tm6000
its working fine on my tm5600. Run fine for more than 5mins without crashing.
But it does crashed everytime when its playing on the first channel and I switch channel in mythtv. I am waiting for usb/serial cable to arrive from ebay to find out why.
I hope to work on the audio part though.
Quoted 8 lines · Dmitri Belimov
Hi
Anyone can watch TV with tm6000 module??
I try mplayer. My PC crashed inside
copy_streamsfunction after some time.With my best regards, Dmitry.
Re: tm6000
In reply to Dmitri BelimovQuoted 7 lines · Dmitri Belimov
Hi
Anyone can watch TV with tm6000 module??
I try mplayer. My PC crashed inside
copy_streamsfunction after some time.With my best regards, Dmitry.
It is still causing panic on my tests. Probably, the routine is still writing something out of the buffer area.
Signature · 2 lines
Cheers, Mauro
Hi Dmitri,
Quoted 12 lines · Dmitri Belimov
Hi
Rework last I2C patch.
Set correct limit for I2C packet.
Use different method for the tm5600/tm6000 and tm6010 to read word.Try this patch.
diff -r
7c0b887911cflinux/drivers/staging/tm6000/tm6000-i2c.c
linux/drivers/staging/tm6000/tm6000-i2c.c line 27
Quoted 4 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +1
-0@@ -24,6 +24,7 @@#include <linux/kernel.h> #include <linux/usb.h> #include <linux/i2c.h> +#include <linux/delay.h>
You probably don't need this.
Quoted 230 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +185
-9#include "compat.h" #include "tm6000.h" @@ -45,11 +46,49 @@printk (KERN_DEBUG "%s at %s: " fmt, \ dev->name, __FUNCTION__ , ##args); } while (0) +static void tm6000_i2c_reset(struct tm6000_core *dev) +{ +tm6000_set_reg (dev,REQ_03_SET_GET_MCU_PIN ,TM6000_GPIO_CLK ,0 ); +msleep (15 ); +tm6000_set_reg (dev,REQ_03_SET_GET_MCU_PIN ,TM6000_GPIO_CLK ,1 ); +msleep (15 ); +} +static int tm6000_i2c_send_regs (struct tm6000_core *dev,unsigned char addr,__u8 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , buf, len); +int rc; +unsigned int tsleep; +unsigned int i2c_packet_limit =16 ; + +if (dev->dev_type ==TM6010 ) + i2c_packet_limit =64 ; + +if (!buf) +return -1 ; + +if (len <1 || len > i2c_packet_limit){ +printk ("Incorrect lenght of i2c packet = %d, limit set to %d\n" , + len, i2c_packet_limit); +return -1 ; + } + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf, len); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 14000us for 64 bytes */ + tsleep = ((len *200 ) +200 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; }/* Generic read - doesn't work fine with 16bit registers */ @@ -58,23 +97,41 @@ {int rc;u8 b[2 ]; +unsigned int i2c_packet_limit =16 ; -if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) && (reg %2 ==0 )) { +if (dev->dev_type ==TM6010 ) + i2c_packet_limit =64 ; + +if (!buf) +return -1 ; + +if (len <1 || len > i2c_packet_limit){ +printk ("Incorrect lenght of i2c packet = %d, limit set to %d\n" , + len, i2c_packet_limit); +return -1 ; + } + +/* capture mutex */ +if ((dev->caps.has_zl10353) && (dev->demod_addr <<1 == addr) + && (reg %2 ==0 )) {/* * Workaround an I2C bug when reading from zl10353 */ reg -=1 ; len +=1 ; - rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , b, len); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , b, len); *buf = b[1 ]; }else { - rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_16_SET_GET_I2C_WR1_RDN , addr | reg <<8 ,0 , buf, len); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf, len); } +/* release mutex */ return rc; }@@ -85,8 +142,137 @@static int tm6000_i2c_recv_regs16 (struct tm6000_core *dev,unsigned char addr,__u16 reg,char *buf,int len) { -return tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR |USB_RECIP_DEVICE , -REQ_14_SET_GET_I2C_WR2_RDN , addr, reg, buf, len); +int rc; +unsigned char ureg; + +if (!buf || len !=2 ) +return -1 ; + +/* capture mutex */ +if (dev->dev_type ==TM6010 ){ + ureg = reg &0xFF ; + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | (reg &0xFF00 ),0 , &ureg,1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +msleep (1400 /1000 ); + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_35_AFTEK_TUNER_READ , + reg,0 , buf, len); + } +else { + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_14_SET_GET_I2C_WR2_RDN , + addr, reg, buf, len); + } + +/* release mutex */ +return rc; +} + +static int tm6000_i2c_read_sequence (struct tm6000_core *dev,unsigned char addr, +__u16 reg,char *buf,int len) +{ +int rc; + +if (dev->dev_type !=TM6010 ) +return -1 ; + +if (!buf) +return -1 ; + +if (len <1 || len >64 ){ +printk ("Incorrect lenght of i2c packet = %d, limit set to 64\n" , + len); +return -1 ; + } + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_IN |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_35_AFTEK_TUNER_READ , + reg,0 , buf, len); +/* release mutex */ +return rc; +} + +static int tm6000_i2c_write_sequence (struct tm6000_core *dev, +unsigned char addr,__u16 reg,char *buf, +int len) +{ +int rc; +unsigned int tsleep; +unsigned int i2c_packet_limit =16 ; + +if (dev->dev_type ==TM6010 ) + i2c_packet_limit =64 ; + +if (!buf) +return -1 ; + +if (len <1 || len > i2c_packet_limit){ +printk ("Incorrect lenght of i2c packet = %d, limit set to %d\n" , + len, i2c_packet_limit); +return -1 ; + } + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_16_SET_GET_I2C_WR1_RDN , + addr | reg <<8 ,0 , buf+1 , len-1 ); + +if (rc <0 ) { +/* release mutex */ +return rc; + } + +/* Calculate delay time, 13800us for 64 bytes */ + tsleep = ((len *200 ) +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; +} + +static int tm6000_i2c_write_uni (struct tm6000_core *dev,unsigned char addr, +__u16 reg,char *buf,int len) +{ +int rc; +unsigned int tsleep; +unsigned int i2c_packet_limit =16 ; + +if (dev->dev_type ==TM6010 ) + i2c_packet_limit =64 ; + +if (!buf) +return -1 ; + +if (len <1 || len > i2c_packet_limit){ +printk ("Incorrect lenght of i2c packet = %d, limit set to %d\n" , + len, i2c_packet_limit); +return -1 ; + } + +/* capture mutex */ + rc =tm6000_read_write_usb (dev,USB_DIR_OUT |USB_TYPE_VENDOR | +USB_RECIP_DEVICE ,REQ_30_I2C_WRITE , + addr | reg <<8 ,0 , buf+1 , len-1 ); + +if (rc <0 ) { +/* release mutex */
linux/drivers/staging/tm6000/tm6000-i2c.c line 276
Quoted 10 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +9
-0+return rc; + } + +/* Calculate delay time, 14800us for 64 bytes */ + tsleep = ((len *200 ) +1000 +1000 ) /1000 ; +msleep (tsleep); + +/* release mutex */ +return rc; }
There are some troubles here that I noticed on your first patch: you're adding some new functions that aren't used on the code, generating some warnings. Please remove them or use.
Quoted 6 lines
linux/drivers/staging/tm6000/tm6000-i2c.c +0
-0static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,With my best regards, Dmitry.
Signature · 2 lines
Cheers, Mauro