Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] introduce gspca-stk1135: Syntek STK1135 driver

Hello,
this is a new gspca driver for Syntek STK1135 webcams. The code is completely
new, but register values are based on Syntekdriver (stk11xx) by Nicolas VIVIEN
(http://syntekdriver.sourceforge.net).
Only one webcam type is supported now - vendor 0x174f, device 0x6a31.
It's Asus F5RL laptop flippable webcam with MT9M112.
The camera works better than in Windows - initializes much faster and
provides more resolutions (the sensor can do almost any resolution - just
add it to the stk1135_modes[] - could this feature be somehow used by
applications to avoid SW scaling?).
Autoflip works too - when the camera is flipped around, the image is flipped
automatically.

Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>

authored by

Ondrej Zary and committed by
Mauro Carvalho Chehab
4ab0620b d48de1c7

+753
+9
drivers/media/usb/gspca/Kconfig
··· 338 338 To compile this driver as a module, choose M here: the 339 339 module will be called gspca_stk014. 340 340 341 + config USB_GSPCA_STK1135 342 + tristate "Syntek STK1135 USB Camera Driver" 343 + depends on VIDEO_V4L2 && USB_GSPCA 344 + help 345 + Say Y here if you want support for cameras based on the STK1135 chip. 346 + 347 + To compile this driver as a module, choose M here: the 348 + module will be called gspca_stk1135. 349 + 341 350 config USB_GSPCA_STV0680 342 351 tristate "STV0680 USB Camera Driver" 343 352 depends on VIDEO_V4L2 && USB_GSPCA
+2
drivers/media/usb/gspca/Makefile
··· 34 34 obj-$(CONFIG_USB_GSPCA_SQ930X) += gspca_sq930x.o 35 35 obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o 36 36 obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o 37 + obj-$(CONFIG_USB_GSPCA_STK1135) += gspca_stk1135.o 37 38 obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o 38 39 obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o 39 40 obj-$(CONFIG_USB_GSPCA_TOPRO) += gspca_topro.o ··· 79 78 gspca_sq905c-objs := sq905c.o 80 79 gspca_sq930x-objs := sq930x.o 81 80 gspca_stk014-objs := stk014.o 81 + gspca_stk1135-objs := stk1135.o 82 82 gspca_stv0680-objs := stv0680.o 83 83 gspca_sunplus-objs := sunplus.o 84 84 gspca_t613-objs := t613.o
+685
drivers/media/usb/gspca/stk1135.c
··· 1 + /* 2 + * Syntek STK1135 subdriver 3 + * 4 + * Copyright (c) 2013 Ondrej Zary 5 + * 6 + * Based on Syntekdriver (stk11xx) by Nicolas VIVIEN: 7 + * http://syntekdriver.sourceforge.net 8 + * 9 + * This program is free software; you can redistribute it and/or modify 10 + * it under the terms of the GNU General Public License as published by 11 + * the Free Software Foundation; either version 2 of the License, or 12 + * any later version. 13 + * 14 + * This program is distributed in the hope that it will be useful, 15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 + * GNU General Public License for more details. 18 + * 19 + * You should have received a copy of the GNU General Public License 20 + * along with this program; if not, write to the Free Software 21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 + */ 23 + 24 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 25 + 26 + #define MODULE_NAME "stk1135" 27 + 28 + #include "gspca.h" 29 + #include "stk1135.h" 30 + 31 + MODULE_AUTHOR("Ondrej Zary"); 32 + MODULE_DESCRIPTION("Syntek STK1135 USB Camera Driver"); 33 + MODULE_LICENSE("GPL"); 34 + 35 + 36 + /* specific webcam descriptor */ 37 + struct sd { 38 + struct gspca_dev gspca_dev; /* !! must be the first item */ 39 + 40 + u8 pkt_seq; 41 + u8 sensor_page; 42 + 43 + bool flip_status; 44 + u8 flip_debounce; 45 + 46 + struct v4l2_ctrl *hflip; 47 + struct v4l2_ctrl *vflip; 48 + }; 49 + 50 + static const struct v4l2_pix_format stk1135_modes[] = { 51 + {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 52 + .bytesperline = 160, 53 + .sizeimage = 160 * 120, 54 + .colorspace = V4L2_COLORSPACE_SRGB}, 55 + {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 56 + .bytesperline = 176, 57 + .sizeimage = 176 * 144, 58 + .colorspace = V4L2_COLORSPACE_SRGB}, 59 + {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 60 + .bytesperline = 320, 61 + .sizeimage = 320 * 240, 62 + .colorspace = V4L2_COLORSPACE_SRGB}, 63 + {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 64 + .bytesperline = 352, 65 + .sizeimage = 352 * 288, 66 + .colorspace = V4L2_COLORSPACE_SRGB}, 67 + {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 68 + .bytesperline = 640, 69 + .sizeimage = 640 * 480, 70 + .colorspace = V4L2_COLORSPACE_SRGB}, 71 + {720, 576, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 72 + .bytesperline = 720, 73 + .sizeimage = 720 * 576, 74 + .colorspace = V4L2_COLORSPACE_SRGB}, 75 + {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 76 + .bytesperline = 800, 77 + .sizeimage = 800 * 600, 78 + .colorspace = V4L2_COLORSPACE_SRGB}, 79 + {1024, 768, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 80 + .bytesperline = 1024, 81 + .sizeimage = 1024 * 768, 82 + .colorspace = V4L2_COLORSPACE_SRGB}, 83 + {1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 84 + .bytesperline = 1280, 85 + .sizeimage = 1280 * 1024, 86 + .colorspace = V4L2_COLORSPACE_SRGB}, 87 + }; 88 + 89 + /* -- read a register -- */ 90 + static u8 reg_r(struct gspca_dev *gspca_dev, u16 index) 91 + { 92 + struct usb_device *dev = gspca_dev->dev; 93 + int ret; 94 + 95 + if (gspca_dev->usb_err < 0) 96 + return 0; 97 + ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 98 + 0x00, 99 + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 100 + 0x00, 101 + index, 102 + gspca_dev->usb_buf, 1, 103 + 500); 104 + 105 + PDEBUG(D_USBI, "reg_r 0x%x=0x%02x", index, gspca_dev->usb_buf[0]); 106 + if (ret < 0) { 107 + pr_err("reg_r 0x%x err %d\n", index, ret); 108 + gspca_dev->usb_err = ret; 109 + return 0; 110 + } 111 + 112 + return gspca_dev->usb_buf[0]; 113 + } 114 + 115 + /* -- write a register -- */ 116 + static void reg_w(struct gspca_dev *gspca_dev, u16 index, u8 val) 117 + { 118 + int ret; 119 + struct usb_device *dev = gspca_dev->dev; 120 + 121 + if (gspca_dev->usb_err < 0) 122 + return; 123 + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 124 + 0x01, 125 + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 126 + val, 127 + index, 128 + NULL, 129 + 0, 130 + 500); 131 + PDEBUG(D_USBO, "reg_w 0x%x:=0x%02x", index, val); 132 + if (ret < 0) { 133 + pr_err("reg_w 0x%x err %d\n", index, ret); 134 + gspca_dev->usb_err = ret; 135 + } 136 + } 137 + 138 + static void reg_w_mask(struct gspca_dev *gspca_dev, u16 index, u8 val, u8 mask) 139 + { 140 + val = (reg_r(gspca_dev, index) & ~mask) | (val & mask); 141 + reg_w(gspca_dev, index, val); 142 + } 143 + 144 + /* this function is called at probe time */ 145 + static int sd_config(struct gspca_dev *gspca_dev, 146 + const struct usb_device_id *id) 147 + { 148 + gspca_dev->cam.cam_mode = stk1135_modes; 149 + gspca_dev->cam.nmodes = ARRAY_SIZE(stk1135_modes); 150 + return 0; 151 + } 152 + 153 + static int stk1135_serial_wait_ready(struct gspca_dev *gspca_dev) 154 + { 155 + int i = 0; 156 + u8 val; 157 + 158 + do { 159 + val = reg_r(gspca_dev, STK1135_REG_SICTL + 1); 160 + if (i++ > 500) { /* maximum retry count */ 161 + pr_err("serial bus timeout: status=0x%02x\n", val); 162 + return -1; 163 + } 164 + /* repeat if BUSY or WRITE/READ not finished */ 165 + } while ((val & 0x10) || !(val & 0x05)); 166 + 167 + return 0; 168 + } 169 + 170 + static u8 sensor_read_8(struct gspca_dev *gspca_dev, u8 addr) 171 + { 172 + reg_w(gspca_dev, STK1135_REG_SBUSR, addr); 173 + /* begin read */ 174 + reg_w(gspca_dev, STK1135_REG_SICTL, 0x20); 175 + /* wait until finished */ 176 + if (stk1135_serial_wait_ready(gspca_dev)) { 177 + pr_err("Sensor read failed\n"); 178 + return 0; 179 + } 180 + 181 + return reg_r(gspca_dev, STK1135_REG_SBUSR + 1); 182 + } 183 + 184 + static u16 sensor_read_16(struct gspca_dev *gspca_dev, u8 addr) 185 + { 186 + return (sensor_read_8(gspca_dev, addr) << 8) | 187 + sensor_read_8(gspca_dev, 0xf1); 188 + } 189 + 190 + static void sensor_write_8(struct gspca_dev *gspca_dev, u8 addr, u8 data) 191 + { 192 + /* load address and data registers */ 193 + reg_w(gspca_dev, STK1135_REG_SBUSW, addr); 194 + reg_w(gspca_dev, STK1135_REG_SBUSW + 1, data); 195 + /* begin write */ 196 + reg_w(gspca_dev, STK1135_REG_SICTL, 0x01); 197 + /* wait until finished */ 198 + if (stk1135_serial_wait_ready(gspca_dev)) { 199 + pr_err("Sensor write failed\n"); 200 + return; 201 + } 202 + } 203 + 204 + static void sensor_write_16(struct gspca_dev *gspca_dev, u8 addr, u16 data) 205 + { 206 + sensor_write_8(gspca_dev, addr, data >> 8); 207 + sensor_write_8(gspca_dev, 0xf1, data & 0xff); 208 + } 209 + 210 + static void sensor_set_page(struct gspca_dev *gspca_dev, u8 page) 211 + { 212 + struct sd *sd = (struct sd *) gspca_dev; 213 + 214 + if (page != sd->sensor_page) { 215 + sensor_write_16(gspca_dev, 0xf0, page); 216 + sd->sensor_page = page; 217 + } 218 + } 219 + 220 + static u16 sensor_read(struct gspca_dev *gspca_dev, u16 reg) 221 + { 222 + sensor_set_page(gspca_dev, reg >> 8); 223 + return sensor_read_16(gspca_dev, reg & 0xff); 224 + } 225 + 226 + static void sensor_write(struct gspca_dev *gspca_dev, u16 reg, u16 val) 227 + { 228 + sensor_set_page(gspca_dev, reg >> 8); 229 + sensor_write_16(gspca_dev, reg & 0xff, val); 230 + } 231 + 232 + static void sensor_write_mask(struct gspca_dev *gspca_dev, 233 + u16 reg, u16 val, u16 mask) 234 + { 235 + val = (sensor_read(gspca_dev, reg) & ~mask) | (val & mask); 236 + sensor_write(gspca_dev, reg, val); 237 + } 238 + 239 + struct sensor_val { 240 + u16 reg; 241 + u16 val; 242 + }; 243 + 244 + /* configure MT9M112 sensor */ 245 + static void stk1135_configure_mt9m112(struct gspca_dev *gspca_dev) 246 + { 247 + static const struct sensor_val cfg[] = { 248 + /* restart&reset, chip enable, reserved */ 249 + { 0x00d, 0x000b }, { 0x00d, 0x0008 }, { 0x035, 0x0022 }, 250 + /* mode ctl: AWB on, AE both, clip aper corr, defect corr, AE */ 251 + { 0x106, 0x700e }, 252 + 253 + { 0x2dd, 0x18e0 }, /* B-R thresholds, */ 254 + 255 + /* AWB */ 256 + { 0x21f, 0x0180 }, /* Cb and Cr limits */ 257 + { 0x220, 0xc814 }, { 0x221, 0x8080 }, /* lum limits, RGB gain */ 258 + { 0x222, 0xa078 }, { 0x223, 0xa078 }, /* R, B limit */ 259 + { 0x224, 0x5f20 }, { 0x228, 0xea02 }, /* mtx adj lim, adv ctl */ 260 + { 0x229, 0x867a }, /* wide gates */ 261 + 262 + /* Color correction */ 263 + /* imager gains base, delta, delta signs */ 264 + { 0x25e, 0x594c }, { 0x25f, 0x4d51 }, { 0x260, 0x0002 }, 265 + /* AWB adv ctl 2, gain offs */ 266 + { 0x2ef, 0x0008 }, { 0x2f2, 0x0000 }, 267 + /* base matrix signs, scale K1-5, K6-9 */ 268 + { 0x202, 0x00ee }, { 0x203, 0x3923 }, { 0x204, 0x0724 }, 269 + /* base matrix coef */ 270 + { 0x209, 0x00cd }, { 0x20a, 0x0093 }, { 0x20b, 0x0004 },/*K1-3*/ 271 + { 0x20c, 0x005c }, { 0x20d, 0x00d9 }, { 0x20e, 0x0053 },/*K4-6*/ 272 + { 0x20f, 0x0008 }, { 0x210, 0x0091 }, { 0x211, 0x00cf },/*K7-9*/ 273 + { 0x215, 0x0000 }, /* delta mtx signs */ 274 + /* delta matrix coef */ 275 + { 0x216, 0x0000 }, { 0x217, 0x0000 }, { 0x218, 0x0000 },/*D1-3*/ 276 + { 0x219, 0x0000 }, { 0x21a, 0x0000 }, { 0x21b, 0x0000 },/*D4-6*/ 277 + { 0x21c, 0x0000 }, { 0x21d, 0x0000 }, { 0x21e, 0x0000 },/*D7-9*/ 278 + /* enable & disable manual WB to apply color corr. settings */ 279 + { 0x106, 0xf00e }, { 0x106, 0x700e }, 280 + 281 + /* Lens shading correction */ 282 + { 0x180, 0x0007 }, /* control */ 283 + /* vertical knee 0, 2+1, 4+3 */ 284 + { 0x181, 0xde13 }, { 0x182, 0xebe2 }, { 0x183, 0x00f6 }, /* R */ 285 + { 0x184, 0xe114 }, { 0x185, 0xeadd }, { 0x186, 0xfdf6 }, /* G */ 286 + { 0x187, 0xe511 }, { 0x188, 0xede6 }, { 0x189, 0xfbf7 }, /* B */ 287 + /* horizontal knee 0, 2+1, 4+3, 5 */ 288 + { 0x18a, 0xd613 }, { 0x18b, 0xedec }, /* R .. */ 289 + { 0x18c, 0xf9f2 }, { 0x18d, 0x0000 }, /* .. R */ 290 + { 0x18e, 0xd815 }, { 0x18f, 0xe9ea }, /* G .. */ 291 + { 0x190, 0xf9f1 }, { 0x191, 0x0002 }, /* .. G */ 292 + { 0x192, 0xde10 }, { 0x193, 0xefef }, /* B .. */ 293 + { 0x194, 0xfbf4 }, { 0x195, 0x0002 }, /* .. B */ 294 + /* vertical knee 6+5, 8+7 */ 295 + { 0x1b6, 0x0e06 }, { 0x1b7, 0x2713 }, /* R */ 296 + { 0x1b8, 0x1106 }, { 0x1b9, 0x2713 }, /* G */ 297 + { 0x1ba, 0x0c03 }, { 0x1bb, 0x2a0f }, /* B */ 298 + /* horizontal knee 7+6, 9+8, 10 */ 299 + { 0x1bc, 0x1208 }, { 0x1bd, 0x1a16 }, { 0x1be, 0x0022 }, /* R */ 300 + { 0x1bf, 0x150a }, { 0x1c0, 0x1c1a }, { 0x1c1, 0x002d }, /* G */ 301 + { 0x1c2, 0x1109 }, { 0x1c3, 0x1414 }, { 0x1c4, 0x002a }, /* B */ 302 + { 0x106, 0x740e }, /* enable lens shading correction */ 303 + 304 + /* Gamma correction - context A */ 305 + { 0x153, 0x0b03 }, { 0x154, 0x4722 }, { 0x155, 0xac82 }, 306 + { 0x156, 0xdac7 }, { 0x157, 0xf5e9 }, { 0x158, 0xff00 }, 307 + /* Gamma correction - context B */ 308 + { 0x1dc, 0x0b03 }, { 0x1dd, 0x4722 }, { 0x1de, 0xac82 }, 309 + { 0x1df, 0xdac7 }, { 0x1e0, 0xf5e9 }, { 0x1e1, 0xff00 }, 310 + 311 + /* output format: RGB, invert output pixclock, output bayer */ 312 + { 0x13a, 0x4300 }, { 0x19b, 0x4300 }, /* for context A, B */ 313 + { 0x108, 0x0180 }, /* format control - enable bayer row flip */ 314 + 315 + { 0x22f, 0xd100 }, { 0x29c, 0xd100 }, /* AE A, B */ 316 + 317 + /* default prg conf, prg ctl - by 0x2d2, prg advance - PA1 */ 318 + { 0x2d2, 0x0000 }, { 0x2cc, 0x0004 }, { 0x2cb, 0x0001 }, 319 + 320 + { 0x22e, 0x0c3c }, { 0x267, 0x1010 }, /* AE tgt ctl, gain lim */ 321 + 322 + /* PLL */ 323 + { 0x065, 0xa000 }, /* clk ctl - enable PLL (clear bit 14) */ 324 + { 0x066, 0x2003 }, { 0x067, 0x0501 }, /* PLL M=128, N=3, P=1 */ 325 + { 0x065, 0x2000 }, /* disable PLL bypass (clear bit 15) */ 326 + 327 + { 0x005, 0x01b8 }, { 0x007, 0x00d8 }, /* horiz blanking B, A */ 328 + 329 + /* AE line size, shutter delay limit */ 330 + { 0x239, 0x06c0 }, { 0x23b, 0x040e }, /* for context A */ 331 + { 0x23a, 0x06c0 }, { 0x23c, 0x0564 }, /* for context B */ 332 + /* shutter width basis 60Hz, 50Hz */ 333 + { 0x257, 0x0208 }, { 0x258, 0x0271 }, /* for context A */ 334 + { 0x259, 0x0209 }, { 0x25a, 0x0271 }, /* for context B */ 335 + 336 + { 0x25c, 0x120d }, { 0x25d, 0x1712 }, /* flicker 60Hz, 50Hz */ 337 + { 0x264, 0x5e1c }, /* reserved */ 338 + /* flicker, AE gain limits, gain zone limits */ 339 + { 0x25b, 0x0003 }, { 0x236, 0x7810 }, { 0x237, 0x8304 }, 340 + 341 + { 0x008, 0x0021 }, /* vert blanking A */ 342 + }; 343 + int i; 344 + u16 width, height; 345 + 346 + for (i = 0; i < ARRAY_SIZE(cfg); i++) 347 + sensor_write(gspca_dev, cfg[i].reg, cfg[i].val); 348 + 349 + /* set output size */ 350 + width = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].width; 351 + height = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].height; 352 + if (width <= 640) { /* use context A (half readout speed by default) */ 353 + sensor_write(gspca_dev, 0x1a7, width); 354 + sensor_write(gspca_dev, 0x1aa, height); 355 + /* set read mode context A */ 356 + sensor_write(gspca_dev, 0x0c8, 0x0000); 357 + /* set resize, read mode, vblank, hblank context A */ 358 + sensor_write(gspca_dev, 0x2c8, 0x0000); 359 + } else { /* use context B (full readout speed by default) */ 360 + sensor_write(gspca_dev, 0x1a1, width); 361 + sensor_write(gspca_dev, 0x1a4, height); 362 + /* set read mode context B */ 363 + sensor_write(gspca_dev, 0x0c8, 0x0008); 364 + /* set resize, read mode, vblank, hblank context B */ 365 + sensor_write(gspca_dev, 0x2c8, 0x040b); 366 + } 367 + } 368 + 369 + static void stk1135_configure_clock(struct gspca_dev *gspca_dev) 370 + { 371 + /* configure SCLKOUT */ 372 + reg_w(gspca_dev, STK1135_REG_TMGEN, 0x12); 373 + /* set 1 clock per pixel */ 374 + /* and positive edge clocked pulse high when pixel counter = 0 */ 375 + reg_w(gspca_dev, STK1135_REG_TCP1 + 0, 0x41); 376 + reg_w(gspca_dev, STK1135_REG_TCP1 + 1, 0x00); 377 + reg_w(gspca_dev, STK1135_REG_TCP1 + 2, 0x00); 378 + reg_w(gspca_dev, STK1135_REG_TCP1 + 3, 0x00); 379 + 380 + /* enable CLKOUT for sensor */ 381 + reg_w(gspca_dev, STK1135_REG_SENSO + 0, 0x10); 382 + /* disable STOP clock */ 383 + reg_w(gspca_dev, STK1135_REG_SENSO + 1, 0x00); 384 + /* set lower 8 bits of PLL feedback divider */ 385 + reg_w(gspca_dev, STK1135_REG_SENSO + 3, 0x07); 386 + /* set other PLL parameters */ 387 + reg_w(gspca_dev, STK1135_REG_PLLFD, 0x06); 388 + /* enable timing generator */ 389 + reg_w(gspca_dev, STK1135_REG_TMGEN, 0x80); 390 + /* enable PLL */ 391 + reg_w(gspca_dev, STK1135_REG_SENSO + 2, 0x04); 392 + 393 + /* set serial interface clock divider (30MHz/0x1f*16+2) = 60240 kHz) */ 394 + reg_w(gspca_dev, STK1135_REG_SICTL + 2, 0x1f); 395 + } 396 + 397 + static void stk1135_camera_disable(struct gspca_dev *gspca_dev) 398 + { 399 + /* set capture end Y position to 0 */ 400 + reg_w(gspca_dev, STK1135_REG_CIEPO + 2, 0x00); 401 + reg_w(gspca_dev, STK1135_REG_CIEPO + 3, 0x00); 402 + /* disable capture */ 403 + reg_w_mask(gspca_dev, STK1135_REG_SCTRL, 0x00, 0x80); 404 + 405 + /* enable sensor standby and diasble chip enable */ 406 + sensor_write_mask(gspca_dev, 0x00d, 0x0004, 0x000c); 407 + 408 + /* disable PLL */ 409 + reg_w_mask(gspca_dev, STK1135_REG_SENSO + 2, 0x00, 0x01); 410 + /* disable timing generator */ 411 + reg_w(gspca_dev, STK1135_REG_TMGEN, 0x00); 412 + /* enable STOP clock */ 413 + reg_w(gspca_dev, STK1135_REG_SENSO + 1, 0x20); 414 + /* disable CLKOUT for sensor */ 415 + reg_w(gspca_dev, STK1135_REG_SENSO, 0x00); 416 + 417 + /* disable sensor (GPIO5) and enable GPIO0,3,6 (?) - sensor standby? */ 418 + reg_w(gspca_dev, STK1135_REG_GCTRL, 0x49); 419 + } 420 + 421 + /* this function is called at probe and resume time */ 422 + static int sd_init(struct gspca_dev *gspca_dev) 423 + { 424 + u16 sensor_id; 425 + char *sensor_name; 426 + struct sd *sd = (struct sd *) gspca_dev; 427 + 428 + /* set GPIO3,4,5,6 direction to output */ 429 + reg_w(gspca_dev, STK1135_REG_GCTRL + 2, 0x78); 430 + /* enable sensor (GPIO5) */ 431 + reg_w(gspca_dev, STK1135_REG_GCTRL, (1 << 5)); 432 + /* disable ROM interface */ 433 + reg_w(gspca_dev, STK1135_REG_GCTRL + 3, 0x80); 434 + /* enable interrupts from GPIO8 (flip sensor) and GPIO9 (???) */ 435 + reg_w(gspca_dev, STK1135_REG_ICTRL + 1, 0x00); 436 + reg_w(gspca_dev, STK1135_REG_ICTRL + 3, 0x03); 437 + /* enable remote wakeup from GPIO9 (???) */ 438 + reg_w(gspca_dev, STK1135_REG_RMCTL + 1, 0x00); 439 + reg_w(gspca_dev, STK1135_REG_RMCTL + 3, 0x02); 440 + 441 + /* reset serial interface */ 442 + reg_w(gspca_dev, STK1135_REG_SICTL, 0x80); 443 + reg_w(gspca_dev, STK1135_REG_SICTL, 0x00); 444 + /* set sensor address */ 445 + reg_w(gspca_dev, STK1135_REG_SICTL + 3, 0xba); 446 + /* disable alt 2-wire serial interface */ 447 + reg_w(gspca_dev, STK1135_REG_ASIC + 3, 0x00); 448 + 449 + stk1135_configure_clock(gspca_dev); 450 + 451 + /* read sensor ID */ 452 + sd->sensor_page = 0xff; 453 + sensor_id = sensor_read(gspca_dev, 0x000); 454 + 455 + switch (sensor_id) { 456 + case 0x148c: 457 + sensor_name = "MT9M112"; 458 + break; 459 + default: 460 + sensor_name = "unknown"; 461 + } 462 + pr_info("Detected sensor type %s (0x%x)\n", sensor_name, sensor_id); 463 + 464 + stk1135_camera_disable(gspca_dev); 465 + 466 + return gspca_dev->usb_err; 467 + } 468 + 469 + /* -- start the camera -- */ 470 + static int sd_start(struct gspca_dev *gspca_dev) 471 + { 472 + struct sd *sd = (struct sd *) gspca_dev; 473 + u16 width, height; 474 + 475 + /* enable sensor (GPIO5) */ 476 + reg_w(gspca_dev, STK1135_REG_GCTRL, (1 << 5)); 477 + 478 + stk1135_configure_clock(gspca_dev); 479 + 480 + /* set capture start position X = 0, Y = 0 */ 481 + reg_w(gspca_dev, STK1135_REG_CISPO + 0, 0x00); 482 + reg_w(gspca_dev, STK1135_REG_CISPO + 1, 0x00); 483 + reg_w(gspca_dev, STK1135_REG_CISPO + 2, 0x00); 484 + reg_w(gspca_dev, STK1135_REG_CISPO + 3, 0x00); 485 + 486 + /* set capture end position */ 487 + width = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].width; 488 + height = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].height; 489 + reg_w(gspca_dev, STK1135_REG_CIEPO + 0, width & 0xff); 490 + reg_w(gspca_dev, STK1135_REG_CIEPO + 1, width >> 8); 491 + reg_w(gspca_dev, STK1135_REG_CIEPO + 2, height & 0xff); 492 + reg_w(gspca_dev, STK1135_REG_CIEPO + 3, height >> 8); 493 + 494 + /* set 8-bit mode */ 495 + reg_w(gspca_dev, STK1135_REG_SCTRL, 0x20); 496 + 497 + stk1135_configure_mt9m112(gspca_dev); 498 + 499 + /* enable capture */ 500 + reg_w_mask(gspca_dev, STK1135_REG_SCTRL, 0x80, 0x80); 501 + 502 + if (gspca_dev->usb_err >= 0) 503 + PDEBUG(D_STREAM, "camera started alt: 0x%02x", 504 + gspca_dev->alt); 505 + 506 + sd->pkt_seq = 0; 507 + 508 + return gspca_dev->usb_err; 509 + } 510 + 511 + static void sd_stopN(struct gspca_dev *gspca_dev) 512 + { 513 + struct usb_device *dev = gspca_dev->dev; 514 + 515 + usb_set_interface(dev, gspca_dev->iface, 0); 516 + 517 + stk1135_camera_disable(gspca_dev); 518 + 519 + PDEBUG(D_STREAM, "camera stopped"); 520 + } 521 + 522 + static void sd_pkt_scan(struct gspca_dev *gspca_dev, 523 + u8 *data, /* isoc packet */ 524 + int len) /* iso packet length */ 525 + { 526 + struct sd *sd = (struct sd *) gspca_dev; 527 + int skip = sizeof(struct stk1135_pkt_header); 528 + bool flip; 529 + enum gspca_packet_type pkt_type = INTER_PACKET; 530 + struct stk1135_pkt_header *hdr = (void *)data; 531 + u8 seq; 532 + 533 + if (len < 4) { 534 + PDEBUG(D_PACK, "received short packet (less than 4 bytes)"); 535 + return; 536 + } 537 + 538 + /* GPIO 8 is flip sensor (1 = normal position, 0 = flipped to back) */ 539 + flip = !(le16_to_cpu(hdr->gpio) & (1 << 8)); 540 + /* it's a switch, needs software debounce */ 541 + if (sd->flip_status != flip) 542 + sd->flip_debounce++; 543 + else 544 + sd->flip_debounce = 0; 545 + 546 + /* check sequence number (not present in new frame packets) */ 547 + if (!(hdr->flags & STK1135_HDR_FRAME_START)) { 548 + seq = hdr->seq & STK1135_HDR_SEQ_MASK; 549 + if (seq != sd->pkt_seq) { 550 + PDEBUG(D_PACK, "received out-of-sequence packet"); 551 + /* resync sequence and discard packet */ 552 + sd->pkt_seq = seq; 553 + gspca_dev->last_packet_type = DISCARD_PACKET; 554 + return; 555 + } 556 + } 557 + sd->pkt_seq++; 558 + if (sd->pkt_seq > STK1135_HDR_SEQ_MASK) 559 + sd->pkt_seq = 0; 560 + 561 + if (len == sizeof(struct stk1135_pkt_header)) 562 + return; 563 + 564 + if (hdr->flags & STK1135_HDR_FRAME_START) { /* new frame */ 565 + skip = 8; /* the header is longer */ 566 + gspca_frame_add(gspca_dev, LAST_PACKET, data, 0); 567 + pkt_type = FIRST_PACKET; 568 + } 569 + gspca_frame_add(gspca_dev, pkt_type, data + skip, len - skip); 570 + } 571 + 572 + static void sethflip(struct gspca_dev *gspca_dev, s32 val) 573 + { 574 + struct sd *sd = (struct sd *) gspca_dev; 575 + 576 + if (sd->flip_status) 577 + val = !val; 578 + sensor_write_mask(gspca_dev, 0x020, val ? 0x0002 : 0x0000 , 0x0002); 579 + } 580 + 581 + static void setvflip(struct gspca_dev *gspca_dev, s32 val) 582 + { 583 + struct sd *sd = (struct sd *) gspca_dev; 584 + 585 + if (sd->flip_status) 586 + val = !val; 587 + sensor_write_mask(gspca_dev, 0x020, val ? 0x0001 : 0x0000 , 0x0001); 588 + } 589 + 590 + static void stk1135_dq_callback(struct gspca_dev *gspca_dev) 591 + { 592 + struct sd *sd = (struct sd *) gspca_dev; 593 + 594 + if (sd->flip_debounce > 100) { 595 + sd->flip_status = !sd->flip_status; 596 + sethflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip)); 597 + setvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->vflip)); 598 + } 599 + } 600 + 601 + static int sd_s_ctrl(struct v4l2_ctrl *ctrl) 602 + { 603 + struct gspca_dev *gspca_dev = 604 + container_of(ctrl->handler, struct gspca_dev, ctrl_handler); 605 + 606 + gspca_dev->usb_err = 0; 607 + 608 + if (!gspca_dev->streaming) 609 + return 0; 610 + 611 + switch (ctrl->id) { 612 + case V4L2_CID_HFLIP: 613 + sethflip(gspca_dev, ctrl->val); 614 + break; 615 + case V4L2_CID_VFLIP: 616 + setvflip(gspca_dev, ctrl->val); 617 + break; 618 + } 619 + 620 + return gspca_dev->usb_err; 621 + } 622 + 623 + static const struct v4l2_ctrl_ops sd_ctrl_ops = { 624 + .s_ctrl = sd_s_ctrl, 625 + }; 626 + 627 + static int sd_init_controls(struct gspca_dev *gspca_dev) 628 + { 629 + struct sd *sd = (struct sd *) gspca_dev; 630 + struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; 631 + 632 + gspca_dev->vdev.ctrl_handler = hdl; 633 + v4l2_ctrl_handler_init(hdl, 2); 634 + sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 635 + V4L2_CID_HFLIP, 0, 1, 1, 0); 636 + sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, 637 + V4L2_CID_VFLIP, 0, 1, 1, 0); 638 + 639 + if (hdl->error) { 640 + pr_err("Could not initialize controls\n"); 641 + return hdl->error; 642 + } 643 + return 0; 644 + } 645 + 646 + /* sub-driver description */ 647 + static const struct sd_desc sd_desc = { 648 + .name = MODULE_NAME, 649 + .config = sd_config, 650 + .init = sd_init, 651 + .init_controls = sd_init_controls, 652 + .start = sd_start, 653 + .stopN = sd_stopN, 654 + .pkt_scan = sd_pkt_scan, 655 + .dq_callback = stk1135_dq_callback, 656 + }; 657 + 658 + /* -- module initialisation -- */ 659 + static const struct usb_device_id device_table[] = { 660 + {USB_DEVICE(0x174f, 0x6a31)}, /* ASUS laptop, MT9M112 sensor */ 661 + {} 662 + }; 663 + MODULE_DEVICE_TABLE(usb, device_table); 664 + 665 + /* -- device connect -- */ 666 + static int sd_probe(struct usb_interface *intf, 667 + const struct usb_device_id *id) 668 + { 669 + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 670 + THIS_MODULE); 671 + } 672 + 673 + static struct usb_driver sd_driver = { 674 + .name = MODULE_NAME, 675 + .id_table = device_table, 676 + .probe = sd_probe, 677 + .disconnect = gspca_disconnect, 678 + #ifdef CONFIG_PM 679 + .suspend = gspca_suspend, 680 + .resume = gspca_resume, 681 + .reset_resume = gspca_resume, 682 + #endif 683 + }; 684 + 685 + module_usb_driver(sd_driver);
+57
drivers/media/usb/gspca/stk1135.h
··· 1 + /* 2 + * STK1135 registers 3 + * 4 + * Copyright (c) 2013 Ondrej Zary 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 + */ 20 + 21 + #define STK1135_REG_GCTRL 0x000 /* GPIO control */ 22 + #define STK1135_REG_ICTRL 0x004 /* Interrupt control */ 23 + #define STK1135_REG_IDATA 0x008 /* Interrupt data */ 24 + #define STK1135_REG_RMCTL 0x00c /* Remote wakeup control */ 25 + #define STK1135_REG_POSVA 0x010 /* Power-on strapping data */ 26 + 27 + #define STK1135_REG_SENSO 0x018 /* Sensor select options */ 28 + #define STK1135_REG_PLLFD 0x01c /* PLL frequency divider */ 29 + 30 + #define STK1135_REG_SCTRL 0x100 /* Sensor control register */ 31 + #define STK1135_REG_DCTRL 0x104 /* Decimation control register */ 32 + #define STK1135_REG_CISPO 0x110 /* Capture image starting position */ 33 + #define STK1135_REG_CIEPO 0x114 /* Capture image ending position */ 34 + #define STK1135_REG_TCTRL 0x120 /* Test data control */ 35 + 36 + #define STK1135_REG_SICTL 0x200 /* Serial interface control register */ 37 + #define STK1135_REG_SBUSW 0x204 /* Serial bus write */ 38 + #define STK1135_REG_SBUSR 0x208 /* Serial bus read */ 39 + #define STK1135_REG_SCSI 0x20c /* Software control serial interface */ 40 + #define STK1135_REG_GSBWP 0x210 /* General serial bus write port */ 41 + #define STK1135_REG_GSBRP 0x214 /* General serial bus read port */ 42 + #define STK1135_REG_ASIC 0x2fc /* Alternate serial interface control */ 43 + 44 + #define STK1135_REG_TMGEN 0x300 /* Timing generator */ 45 + #define STK1135_REG_TCP1 0x350 /* Timing control parameter 1 */ 46 + 47 + struct stk1135_pkt_header { 48 + u8 flags; 49 + u8 seq; 50 + __le16 gpio; 51 + } __packed; 52 + 53 + #define STK1135_HDR_FRAME_START (1 << 7) 54 + #define STK1135_HDR_ODD (1 << 6) 55 + #define STK1135_HDR_I2C_VBLANK (1 << 5) 56 + 57 + #define STK1135_HDR_SEQ_MASK 0x3f