aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/tm6000/tm6000-i2c.c
diff options
context:
space:
mode:
authorDmitri Belimov <d.belimov@gmail.com>2010-04-27 21:32:43 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-05-19 11:58:17 -0400
commit20dead8da8b383004e66eaf884cd9e07ceadbd68 (patch)
tree840a83bfee8e76159c5a7dd5a4fb1d8dbd645714 /drivers/staging/tm6000/tm6000-i2c.c
parenta85675316f24835ce0c3286ee3cb33fa2f24bca7 (diff)
V4L/DVB: tm6000: fix i2c read
Set correct limit for I2C packet. Use different method for the tm5600/tm6000 and tm6010 to read word. [mchehab@redhat.com: Fix CodingStyle] Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/staging/tm6000/tm6000-i2c.c')
-rw-r--r--drivers/staging/tm6000/tm6000-i2c.c81
1 files changed, 77 insertions, 4 deletions
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
index 2ab632b6fd1..94ff489a1bb 100644
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -47,8 +47,38 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
47static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, 47static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr,
48 __u8 reg, char *buf, int len) 48 __u8 reg, char *buf, int len)
49{ 49{
50 return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 50 int rc;
51 REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); 51 unsigned int tsleep;
52 unsigned int i2c_packet_limit = 16;
53
54 if (dev->dev_type == TM6010)
55 i2c_packet_limit = 64;
56
57 if (!buf)
58 return -1;
59
60 if (len < 1 || len > i2c_packet_limit) {
61 printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n",
62 len, i2c_packet_limit);
63 return -1;
64 }
65
66 /* capture mutex */
67 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
68 USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN,
69 addr | reg << 8, 0, buf, len);
70
71 if (rc < 0) {
72 /* release mutex */
73 return rc;
74 }
75
76 /* Calculate delay time, 14000us for 64 bytes */
77 tsleep = ((len * 200) + 200 + 1000) / 1000;
78 msleep(tsleep);
79
80 /* release mutex */
81 return rc;
52} 82}
53 83
54/* Generic read - doesn't work fine with 16bit registers */ 84/* 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,
57{ 87{
58 int rc; 88 int rc;
59 u8 b[2]; 89 u8 b[2];
90 unsigned int i2c_packet_limit = 16;
91
92 if (dev->dev_type == TM6010)
93 i2c_packet_limit = 64;
94
95 if (!buf)
96 return -1;
60 97
98 if (len < 1 || len > i2c_packet_limit) {
99 printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n",
100 len, i2c_packet_limit);
101 return -1;
102 }
103
104 /* capture mutex */
61 if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { 105 if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) {
62 /* 106 /*
63 * Workaround an I2C bug when reading from zl10353 107 * 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,
74 REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); 118 REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len);
75 } 119 }
76 120
121 /* release mutex */
77 return rc; 122 return rc;
78} 123}
79 124
@@ -84,8 +129,36 @@ static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr,
84static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr, 129static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr,
85 __u16 reg, char *buf, int len) 130 __u16 reg, char *buf, int len)
86{ 131{
87 return tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 132 int rc;
88 REQ_14_SET_GET_I2C_WR2_RDN, addr, reg, buf, len); 133 unsigned char ureg;
134
135 if (!buf || len != 2)
136 return -1;
137
138 /* capture mutex */
139 if (dev->dev_type == TM6010) {
140 ureg = reg & 0xFF;
141 rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
142 USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN,
143 addr | (reg & 0xFF00), 0, &ureg, 1);
144
145 if (rc < 0) {
146 /* release mutex */
147 return rc;
148 }
149
150 msleep(1400 / 1000);
151 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
152 USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ,
153 reg, 0, buf, len);
154 } else {
155 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
156 USB_RECIP_DEVICE, REQ_14_SET_GET_I2C_WR2_RDN,
157 addr, reg, buf, len);
158 }
159
160 /* release mutex */
161 return rc;
89} 162}
90 163
91static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap, 164static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,