diff options
author | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 2005-11-09 00:37:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-09 10:56:17 -0500 |
commit | 596d92d5128d308b5a79f21c3e72c87f5fc7e58b (patch) | |
tree | 3957529296b0765e7979f205a9dd0bce7de1eb7a /drivers/media/video/em28xx/em28xx-i2c.c | |
parent | 2b5200a7b19a53969db68c97d379339592ca6a4f (diff) |
[PATCH] v4l: 767: included support for em2800
- Included support for em2800.
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-i2c.c')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-i2c.c | 182 |
1 files changed, 159 insertions, 23 deletions
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 3065ddb4b368..b7360d579a8a 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | em2820-i2c.c - driver for Empia EM2820/2840 USB video capture devices | 2 | em2820-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices |
3 | 3 | ||
4 | Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> | 4 | Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> |
5 | Ludovico Cavedon <cavedon@sssup.it> | 5 | Ludovico Cavedon <cavedon@sssup.it> |
@@ -29,11 +29,6 @@ | |||
29 | #include <media/tuner.h> | 29 | #include <media/tuner.h> |
30 | #include <linux/video_decoder.h> | 30 | #include <linux/video_decoder.h> |
31 | 31 | ||
32 | /* To be moved to compat.h */ | ||
33 | #if !defined(I2C_HW_B_EM2820) | ||
34 | #define I2C_HW_B_EM2820 0x99 | ||
35 | #endif | ||
36 | |||
37 | #include "em2820.h" | 32 | #include "em2820.h" |
38 | 33 | ||
39 | /* ----------------------------------------------------------- */ | 34 | /* ----------------------------------------------------------- */ |
@@ -56,11 +51,132 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | |||
56 | printk(fmt , ##args); } while (0) | 51 | printk(fmt , ##args); } while (0) |
57 | 52 | ||
58 | /* | 53 | /* |
59 | * i2c_send_bytes() | 54 | * em2800_i2c_send_max4() |
55 | * send up to 4 bytes to the i2c device | ||
56 | */ | ||
57 | static int em2800_i2c_send_max4(struct em2820 *dev, unsigned char addr, | ||
58 | char *buf, int len) | ||
59 | { | ||
60 | int ret; | ||
61 | int write_timeout; | ||
62 | unsigned char b2[6]; | ||
63 | BUG_ON(len < 1 || len > 4); | ||
64 | b2[5] = 0x80 + len - 1; | ||
65 | b2[4] = addr; | ||
66 | b2[3] = buf[0]; | ||
67 | if (len > 1) | ||
68 | b2[2] = buf[1]; | ||
69 | if (len > 2) | ||
70 | b2[1] = buf[2]; | ||
71 | if (len > 3) | ||
72 | b2[0] = buf[3]; | ||
73 | |||
74 | ret = dev->em2820_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); | ||
75 | if (ret != 2 + len) { | ||
76 | em2820_warn("writting to i2c device failed (error=%i)\n", ret); | ||
77 | return -EIO; | ||
78 | } | ||
79 | for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; | ||
80 | write_timeout -= 5) { | ||
81 | ret = dev->em2820_read_reg(dev, 0x05); | ||
82 | if (ret == 0x80 + len - 1) | ||
83 | return len; | ||
84 | mdelay(5); | ||
85 | } | ||
86 | em2820_warn("i2c write timed out\n"); | ||
87 | return -EIO; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * em2800_i2c_send_bytes() | ||
92 | */ | ||
93 | static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf, | ||
94 | short len) | ||
95 | { | ||
96 | char *bufPtr = buf; | ||
97 | int ret; | ||
98 | int wrcount = 0; | ||
99 | int count; | ||
100 | int maxLen = 4; | ||
101 | struct em2820 *dev = (struct em2820 *)data; | ||
102 | while (len > 0) { | ||
103 | count = (len > maxLen) ? maxLen : len; | ||
104 | ret = em2800_i2c_send_max4(dev, addr, bufPtr, count); | ||
105 | if (ret > 0) { | ||
106 | len -= count; | ||
107 | bufPtr += count; | ||
108 | wrcount += count; | ||
109 | } else | ||
110 | return (ret < 0) ? ret : -EFAULT; | ||
111 | } | ||
112 | return wrcount; | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * em2800_i2c_check_for_device() | ||
117 | * check if there is a i2c_device at the supplied address | ||
118 | */ | ||
119 | static int em2800_i2c_check_for_device(struct em2820 *dev, unsigned char addr) | ||
120 | { | ||
121 | char msg; | ||
122 | int ret; | ||
123 | int write_timeout; | ||
124 | msg = addr; | ||
125 | ret = dev->em2820_write_regs(dev, 0x04, &msg, 1); | ||
126 | if (ret < 0) { | ||
127 | em2820_warn("setting i2c device address failed (error=%i)\n", | ||
128 | ret); | ||
129 | return ret; | ||
130 | } | ||
131 | msg = 0x84; | ||
132 | ret = dev->em2820_write_regs(dev, 0x05, &msg, 1); | ||
133 | if (ret < 0) { | ||
134 | em2820_warn("preparing i2c read failed (error=%i)\n", ret); | ||
135 | return ret; | ||
136 | } | ||
137 | for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; | ||
138 | write_timeout -= 5) { | ||
139 | unsigned msg = dev->em2820_read_reg(dev, 0x5); | ||
140 | if (msg == 0x94) | ||
141 | return -ENODEV; | ||
142 | else if (msg == 0x84) | ||
143 | return 0; | ||
144 | mdelay(5); | ||
145 | } | ||
146 | return -ENODEV; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * em2800_i2c_recv_bytes() | ||
151 | * read from the i2c device | ||
152 | */ | ||
153 | static int em2800_i2c_recv_bytes(struct em2820 *dev, unsigned char addr, | ||
154 | char *buf, int len) | ||
155 | { | ||
156 | int ret; | ||
157 | /* check for the device and set i2c read address */ | ||
158 | ret = em2800_i2c_check_for_device(dev, addr); | ||
159 | if (ret) { | ||
160 | em2820_warn | ||
161 | ("preparing read at i2c address 0x%x failed (error=%i)\n", | ||
162 | addr, ret); | ||
163 | return ret; | ||
164 | } | ||
165 | ret = dev->em2820_read_reg_req_len(dev, 0x0, 0x3, buf, len); | ||
166 | if (ret < 0) { | ||
167 | em2820_warn("reading from i2c device at 0x%x failed (error=%i)", | ||
168 | addr, ret); | ||
169 | return ret; | ||
170 | } | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * em2820_i2c_send_bytes() | ||
60 | * untested for more than 4 bytes | 176 | * untested for more than 4 bytes |
61 | */ | 177 | */ |
62 | static int i2c_send_bytes(void *data, unsigned char addr, char *buf, short len, | 178 | static int em2820_i2c_send_bytes(void *data, unsigned char addr, char *buf, |
63 | int stop) | 179 | short len, int stop) |
64 | { | 180 | { |
65 | int wrcount = 0; | 181 | int wrcount = 0; |
66 | struct em2820 *dev = (struct em2820 *)data; | 182 | struct em2820 *dev = (struct em2820 *)data; |
@@ -71,11 +187,11 @@ static int i2c_send_bytes(void *data, unsigned char addr, char *buf, short len, | |||
71 | } | 187 | } |
72 | 188 | ||
73 | /* | 189 | /* |
74 | * i2c_recv_byte() | 190 | * em2820_i2c_recv_bytes() |
75 | * read a byte from the i2c device | 191 | * read a byte from the i2c device |
76 | */ | 192 | */ |
77 | static int i2c_recv_bytes(struct em2820 *dev, unsigned char addr, char *buf, | 193 | static int em2820_i2c_recv_bytes(struct em2820 *dev, unsigned char addr, |
78 | int len) | 194 | char *buf, int len) |
79 | { | 195 | { |
80 | int ret; | 196 | int ret; |
81 | ret = dev->em2820_read_reg_req_len(dev, 2, addr, buf, len); | 197 | ret = dev->em2820_read_reg_req_len(dev, 2, addr, buf, len); |
@@ -89,10 +205,10 @@ static int i2c_recv_bytes(struct em2820 *dev, unsigned char addr, char *buf, | |||
89 | } | 205 | } |
90 | 206 | ||
91 | /* | 207 | /* |
92 | * i2c_check_for_device() | 208 | * em2820_i2c_check_for_device() |
93 | * check if there is a i2c_device at the supplied address | 209 | * check if there is a i2c_device at the supplied address |
94 | */ | 210 | */ |
95 | static int i2c_check_for_device(struct em2820 *dev, unsigned char addr) | 211 | static int em2820_i2c_check_for_device(struct em2820 *dev, unsigned char addr) |
96 | { | 212 | { |
97 | char msg; | 213 | char msg; |
98 | int ret; | 214 | int ret; |
@@ -126,18 +242,25 @@ static int em2820_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
126 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | 242 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", |
127 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); | 243 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); |
128 | if (!msgs[i].len) { /* no len: check only for device presence */ | 244 | if (!msgs[i].len) { /* no len: check only for device presence */ |
129 | rc = i2c_check_for_device(dev, addr); | 245 | if (dev->is_em2800) |
246 | rc = em2800_i2c_check_for_device(dev, addr); | ||
247 | else | ||
248 | rc = em2820_i2c_check_for_device(dev, addr); | ||
130 | if (rc < 0) { | 249 | if (rc < 0) { |
131 | dprintk2(" no device\n"); | 250 | dprintk2(" no device\n"); |
132 | return rc; | 251 | return rc; |
133 | } | 252 | } |
134 | 253 | ||
135 | } | 254 | } else if (msgs[i].flags & I2C_M_RD) { |
136 | if (msgs[i].flags & I2C_M_RD) { | ||
137 | /* read bytes */ | 255 | /* read bytes */ |
138 | 256 | if (dev->is_em2800) | |
139 | rc = i2c_recv_bytes(dev, addr, msgs[i].buf, | 257 | rc = em2800_i2c_recv_bytes(dev, addr, |
140 | msgs[i].len); | 258 | msgs[i].buf, |
259 | msgs[i].len); | ||
260 | else | ||
261 | rc = em2820_i2c_recv_bytes(dev, addr, | ||
262 | msgs[i].buf, | ||
263 | msgs[i].len); | ||
141 | if (i2c_debug) { | 264 | if (i2c_debug) { |
142 | for (byte = 0; byte < msgs[i].len; byte++) { | 265 | for (byte = 0; byte < msgs[i].len; byte++) { |
143 | printk(" %02x", msgs[i].buf[byte]); | 266 | printk(" %02x", msgs[i].buf[byte]); |
@@ -149,8 +272,15 @@ static int em2820_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
149 | for (byte = 0; byte < msgs[i].len; byte++) | 272 | for (byte = 0; byte < msgs[i].len; byte++) |
150 | printk(" %02x", msgs[i].buf[byte]); | 273 | printk(" %02x", msgs[i].buf[byte]); |
151 | } | 274 | } |
152 | rc = i2c_send_bytes(dev, addr, msgs[i].buf, msgs[i].len, | 275 | if (dev->is_em2800) |
153 | i == num - 1); | 276 | rc = em2800_i2c_send_bytes(dev, addr, |
277 | msgs[i].buf, | ||
278 | msgs[i].len); | ||
279 | else | ||
280 | rc = em2820_i2c_send_bytes(dev, addr, | ||
281 | msgs[i].buf, | ||
282 | msgs[i].len, | ||
283 | i == num - 1); | ||
154 | if (rc < 0) | 284 | if (rc < 0) |
155 | goto err; | 285 | goto err; |
156 | } | 286 | } |
@@ -171,6 +301,12 @@ static int em2820_i2c_eeprom(struct em2820 *dev, unsigned char *eedata, int len) | |||
171 | int i, err, size = len, block; | 301 | int i, err, size = len, block; |
172 | 302 | ||
173 | dev->i2c_client.addr = 0xa0 >> 1; | 303 | dev->i2c_client.addr = 0xa0 >> 1; |
304 | |||
305 | /* Check if board has eeprom */ | ||
306 | err = i2c_master_recv(&dev->i2c_client, &buf, 0); | ||
307 | if (err < 0) | ||
308 | return -1; | ||
309 | |||
174 | buf = 0; | 310 | buf = 0; |
175 | if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) { | 311 | if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) { |
176 | printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", | 312 | printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", |
@@ -389,7 +525,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c) | |||
389 | rc = i2c_master_recv(c, &buf, 0); | 525 | rc = i2c_master_recv(c, &buf, 0); |
390 | if (rc < 0) | 526 | if (rc < 0) |
391 | continue; | 527 | continue; |
392 | printk(KERN_INFO "%s: found device @ 0x%x [%s]", name, | 528 | printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", name, |
393 | i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); | 529 | i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); |
394 | } | 530 | } |
395 | } | 531 | } |