diff options
author | Dmitri Belimov <d.belimov@gmail.com> | 2010-04-27 21:32:43 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-05-19 11:58:17 -0400 |
commit | 20dead8da8b383004e66eaf884cd9e07ceadbd68 (patch) | |
tree | 840a83bfee8e76159c5a7dd5a4fb1d8dbd645714 /drivers/staging/tm6000/tm6000-i2c.c | |
parent | a85675316f24835ce0c3286ee3cb33fa2f24bca7 (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.c | 81 |
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]"); | |||
47 | static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, | 47 | static 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, | |||
84 | static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr, | 129 | static 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 | ||
91 | static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap, | 164 | static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap, |