vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / media / media-add-ons / usb_webcam / addons / quickcam / QuickCamDevice.cpp
blob48f59cb8d357e0f737daaeffa8a44f3304331fa2
1 /*
2 * Copyright 2004-2008, François Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
4 */
6 #include "QuickCamDevice.h"
7 #include "CamDebug.h"
8 #include "CamSensor.h"
11 const usb_webcam_support_descriptor kSupportedDevices[] = {
12 {{ 0, 0, 0, 0x046d, 0x0840 }, "Logitech", "QuickCam Express", NULL },
13 {{ 0, 0, 0, 0x046d, 0x0850 }, "Logitech", "QuickCam Express LEGO", NULL },
14 {{ 0, 0, 0, 0, 0}, NULL, NULL, NULL }
19 QuickCamDevice::QuickCamDevice(CamDeviceAddon &_addon, BUSBDevice* _device)
20 :CamDevice(_addon, _device)
22 status_t err;
24 // linux seems to infer this sets I2C controller to 8 or 16 bit mode...
25 // sensors will set to the mode they want when probing
26 SetIICBitsMode(8);
27 err = ProbeSensor();
28 if (err < B_OK) {
29 // reset I2C mode to 8 bit as linux driver does
30 SetIICBitsMode(8);
31 // not much we can do anyway
34 fInitStatus = B_OK;
38 QuickCamDevice::~QuickCamDevice()
44 bool
45 QuickCamDevice::SupportsBulk()
47 return true;
51 bool
52 QuickCamDevice::SupportsIsochronous()
54 return true;
58 status_t
59 QuickCamDevice::StartTransfer()
61 SetScale(1);
62 if (Sensor())
63 SetVideoFrame(BRect(0, 0, Sensor()->MaxWidth()-1, Sensor()->MaxHeight()-1));
65 //SetVideoFrame(BRect(0, 0, 320-1, 240-1));
67 DumpRegs();
68 #if 0
69 err = ReadReg(SN9C102_CHIP_CTRL, &r, 1, true);
70 if (err < 0)
71 return err;
72 r |= 0x04;
73 err = WriteReg8(SN9C102_CHIP_CTRL, r);
74 if (err < 0)
75 return err;
76 #endif
77 return CamDevice::StartTransfer();
81 status_t
82 QuickCamDevice::StopTransfer()
84 status_t err;
86 DumpRegs();
87 err = CamDevice::StopTransfer();
88 #if 0
89 // if (err < 0)
90 // return err;
91 err = ReadReg(SN9C102_CHIP_CTRL, &r, 1, true);
92 if (err < 0)
93 return err;
94 r &= ~0x04;
95 err = WriteReg8(SN9C102_CHIP_CTRL, r);
96 if (err < 0)
97 return err;
98 #endif
99 return err;
103 ssize_t
104 QuickCamDevice::WriteReg(uint16 address, uint8 *data, size_t count)
106 PRINT((CH "(%u, @%p, %u)" CT, address, data, count));
107 return SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, address, 0, count, data);
111 ssize_t
112 QuickCamDevice::ReadReg(uint16 address, uint8 *data, size_t count, bool cached)
114 PRINT((CH "(%u, @%p, %u, %d)" CT, address, data, count, cached));
115 memset(data, 0xaa, count); // linux drivers do that without explaining why !?
116 return SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, address, 0, count, data);
120 status_t
121 QuickCamDevice::GetStatusIIC()
123 status_t err = B_ERROR;
124 uint8 status = 0;
125 #warning WRITEME
126 //dprintf(ID "i2c_status: error 0x%08lx, status = %02x\n", err, status);
127 if (err < 0)
128 return err;
129 return (status&0x08)?EIO:0;
133 status_t
134 QuickCamDevice::WaitReadyIIC()
136 #warning WRITEME
137 return EBUSY;
141 ssize_t
142 QuickCamDevice::WriteIIC(uint8 address, uint8 *data, size_t count)
144 int i;
145 uint8 buffer[0x23];
146 if (count > 16)
147 return EINVAL;
148 memset(buffer, 0, sizeof(buffer));
149 buffer[0x20] = Sensor() ? Sensor()->IICWriteAddress() : 0;
150 buffer[0x21] = count - 1;
151 buffer[0x22] = 0x01;
152 for (i = 0; i < count; i++) {
153 buffer[i] = address + i;
154 buffer[i+16] = data[i];
156 return SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, buffer);
160 ssize_t
161 QuickCamDevice::ReadIIC(uint8 address, uint8 *data)
163 return ReadIIC(address, data);
167 ssize_t
168 QuickCamDevice::ReadIIC8(uint8 address, uint8 *data)
170 status_t err;
171 uint8 buffer[0x23];
172 memset(buffer, 0, sizeof(buffer));
173 buffer[0x20] = Sensor() ? Sensor()->IICReadAddress() : 0;
174 buffer[0x21] = 1 - 1;
175 buffer[0x22] = 0x03;
176 buffer[0] = address;
177 err = SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, buffer);
178 PRINT((CH ": SendCommand: %s" CT, strerror(err)));
179 if (err < B_OK)
180 return err;
182 buffer[0] = 0xaa;
183 err = SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, STV_I2C_READ, 0, 0x1, buffer);
184 PRINT((CH ": SendCommand: %s" CT, strerror(err)));
185 if (err < B_OK)
186 return err;
188 *data = buffer[0];
189 PRINT((CH ": 0x%02x" CT, *data));
190 return 1;
194 ssize_t
195 QuickCamDevice::ReadIIC16(uint8 address, uint16 *data)
197 status_t err;
198 uint8 buffer[0x23];
199 memset(buffer, 0, sizeof(buffer));
200 buffer[0x20] = Sensor() ? Sensor()->IICReadAddress() : 0;
201 buffer[0x21] = 1 - 1;
202 buffer[0x22] = 0x03;
203 buffer[0] = address;
204 err = SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, buffer);
205 if (err < B_OK)
206 return err;
208 buffer[0] = 0xaa;
209 buffer[1] = 0xaa;
210 err = SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, STV_I2C_READ, 0, 0x2, buffer);
211 PRINT((CH ": SendCommand: %s" CT, strerror(err)));
212 if (err < B_OK)
213 return err;
215 if (fChipIsBigEndian)
216 *data = B_HOST_TO_BENDIAN_INT16(*(uint16 *)(&buffer[0]));
217 else
218 *data = B_HOST_TO_LENDIAN_INT16(*(uint16 *)(&buffer[0]));
219 PRINT((CH ": 0x%04x" CT, *data));
220 return 2;
224 status_t
225 QuickCamDevice::SetIICBitsMode(size_t bits)
227 switch (bits) {
228 case 8:
229 WriteReg8(STV_REG23, 0);
230 break;
231 case 16:
232 WriteReg8(STV_REG23, 1);
233 break;
234 default:
235 return EINVAL;
237 return B_OK;
241 status_t
242 QuickCamDevice::SendCommand(uint8 dir, uint8 request, uint16 value,
243 uint16 index, uint16 length, void* data)
245 size_t ret;
246 if (!GetDevice())
247 return ENODEV;
248 if (length > GetDevice()->MaxEndpoint0PacketSize())
249 return EINVAL;
250 ret = GetDevice()->ControlTransfer(
251 USB_REQTYPE_VENDOR | dir,
252 request, value, index, length, data);
253 return ret;
257 QuickCamDeviceAddon::QuickCamDeviceAddon(WebCamMediaAddOn* webcam)
258 : CamDeviceAddon(webcam)
260 SetSupportedDevices(kSupportedDevices);
264 QuickCamDeviceAddon::~QuickCamDeviceAddon()
269 const char *
270 QuickCamDeviceAddon::BrandName()
272 return "QuickCam";
276 QuickCamDevice *
277 QuickCamDeviceAddon::Instantiate(CamRoster &roster, BUSBDevice *from)
279 return new QuickCamDevice(*this, from);
283 extern "C" status_t
284 B_WEBCAM_MKINTFUNC(quickcam)
285 (WebCamMediaAddOn* webcam, CamDeviceAddon **addon)
287 *addon = new QuickCamDeviceAddon(webcam);
288 return B_OK;