^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * stk-webcam.c : Driver for Syntek 1125 USB webcam controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2006 Nicolas VIVIEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2007-2008 Jaime Velasco Juan <jsagarribay@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Some parts are inspired from cafe_ccic.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright 2006-2007 Jonathan Corbet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <media/v4l2-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <media/v4l2-event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "stk-webcam.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static int hflip = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) module_param(hflip, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) MODULE_PARM_DESC(hflip, "Horizontal image flip (mirror). Defaults to 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int vflip = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) module_param(vflip, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MODULE_PARM_DESC(vflip, "Vertical image flip. Defaults to 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) module_param(debug, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) MODULE_PARM_DESC(debug, "Debug v4l ioctls. Defaults to 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) MODULE_AUTHOR("Jaime Velasco Juan <jsagarribay@gmail.com> and Nicolas VIVIEN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) MODULE_DESCRIPTION("Syntek DC1125 webcam driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* Some cameras have audio interfaces, we aren't interested in those */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static const struct usb_device_id stkwebcam_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) { USB_DEVICE_AND_INTERFACE_INFO(0x174f, 0xa311, 0xff, 0xff, 0xff) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) { USB_DEVICE_AND_INTERFACE_INFO(0x05e1, 0x0501, 0xff, 0xff, 0xff) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) MODULE_DEVICE_TABLE(usb, stkwebcam_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * The stk webcam laptop module is mounted upside down in some laptops :(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * Some background information (thanks to Hans de Goede for providing this):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * 1) Once upon a time the stkwebcam driver was written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * 2) The webcam in question was used mostly in Asus laptop models, including
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * the laptop of the original author of the driver, and in these models, in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * typical Asus fashion (see the long long list for uvc cams inside v4l-utils),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * they mounted the webcam-module the wrong way up. So the hflip and vflip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * module options were given a default value of 1 (the correct value for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * upside down mounted models)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * 3) Years later I got a bug report from a user with a laptop with stkwebcam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * where the module was actually mounted the right way up, and thus showed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * upside down under Linux. So now I was facing the choice of 2 options:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * a) Add a not-upside-down list to stkwebcam, which overrules the default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * b) Do it like all the other drivers do, and make the default right for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * cams mounted the proper way and add an upside-down model list, with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * models where we need to flip-by-default.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Despite knowing that going b) would cause a period of pain where we were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * building the table I opted to go for option b), since a) is just too ugly,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * and worse different from how every other driver does it leading to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * confusion in the long run. This change was made in kernel 3.6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * So for any user report about upside-down images since kernel 3.6 ask them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * to provide the output of 'sudo dmidecode' so the laptop can be added in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * the table below.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static const struct dmi_system_id stk_upside_down_dmi_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) .ident = "ASUS G1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) DMI_MATCH(DMI_PRODUCT_NAME, "G1")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .ident = "ASUS F3JC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) DMI_MATCH(DMI_PRODUCT_NAME, "F3JC")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .ident = "T12Rg-H",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) DMI_MATCH(DMI_SYS_VENDOR, "HCL Infosystems Limited"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) DMI_MATCH(DMI_PRODUCT_NAME, "T12Rg-H")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .ident = "ASUS A6VM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) DMI_MATCH(DMI_PRODUCT_NAME, "A6VM")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * Basic stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int stk_camera_write_reg(struct stk_camera *dev, u16 index, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct usb_device *udev = dev->udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int stk_camera_read_reg(struct stk_camera *dev, u16 index, u8 *value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct usb_device *udev = dev->udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) unsigned char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) buf = kmalloc(sizeof(u8), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) sizeof(u8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *value = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int stk_start_stream(struct stk_camera *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) u8 value_116, value_117;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (!is_present(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (!is_memallocd(dev) || !is_initialised(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) pr_err("FIXME: Buffers are not allocated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ret = usb_set_interface(dev->udev, 0, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) pr_err("usb_set_interface failed !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (stk_sensor_wakeup(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) pr_err("error awaking the sensor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) stk_camera_read_reg(dev, 0x0116, &value_116);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) stk_camera_read_reg(dev, 0x0117, &value_117);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) stk_camera_write_reg(dev, 0x0116, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) stk_camera_write_reg(dev, 0x0117, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) stk_camera_read_reg(dev, 0x0100, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) stk_camera_write_reg(dev, 0x0100, value | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) stk_camera_write_reg(dev, 0x0116, value_116);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) stk_camera_write_reg(dev, 0x0117, value_117);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) for (i = 0; i < MAX_ISO_BUFS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (dev->isobufs[i].urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ret = usb_submit_urb(dev->isobufs[i].urb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) atomic_inc(&dev->urbs_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) set_streaming(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static int stk_stop_stream(struct stk_camera *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (is_present(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) stk_camera_read_reg(dev, 0x0100, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) stk_camera_write_reg(dev, 0x0100, value & ~0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (dev->isobufs != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) for (i = 0; i < MAX_ISO_BUFS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (dev->isobufs[i].urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) usb_kill_urb(dev->isobufs[i].urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) unset_streaming(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (usb_set_interface(dev->udev, 0, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) pr_err("usb_set_interface failed !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (stk_sensor_sleep(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) pr_err("error suspending the sensor\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * This seems to be the shortest init sequence we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * must do in order to find the sensor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * Bit 5 of reg. 0x0000 here is important, when reset to 0 the sensor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * is also reset. Maybe powers down it?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * Rest of values don't make a difference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static struct regval stk1125_initvals[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /*TODO: What means this sequence? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {0x0000, 0x24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {0x0100, 0x21},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {0x0002, 0x68},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {0x0003, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {0x0005, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {0x0007, 0x03},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {0x000d, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {0x000f, 0x02},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {0x0300, 0x12},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {0x0350, 0x41},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {0x0351, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {0x0352, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {0x0353, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {0x0018, 0x10},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {0x0019, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {0x001b, 0x0e},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {0x001c, 0x46},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {0x0300, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {0x001a, 0x04},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {0x0110, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {0x0111, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {0x0112, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {0x0113, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {0xffff, 0xff},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static int stk_initialise(struct stk_camera *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct regval *rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (!is_present(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (is_initialised(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) rv = stk1125_initvals;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) while (rv->reg != 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) ret = stk_camera_write_reg(dev, rv->reg, rv->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) rv++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (stk_sensor_init(dev) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) set_initialised(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* *********************************************** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * This function is called as an URB transfert is complete (Isochronous pipe).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * So, the traitement is done in interrupt time, so it has be fast, not crash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * and not stall. Neat.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) static void stk_isoc_handler(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int framelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) unsigned char *fill = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) unsigned char *iso_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct stk_camera *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct stk_sio_buffer *fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) dev = (struct stk_camera *) urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) pr_err("isoc_handler called with NULL device !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (urb->status == -ENOENT || urb->status == -ECONNRESET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) || urb->status == -ESHUTDOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) atomic_dec(&dev->urbs_used);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) spin_lock_irqsave(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (urb->status != -EINPROGRESS && urb->status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) pr_err("isoc_handler: urb->status == %d\n", urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) goto resubmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (list_empty(&dev->sio_avail)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /*FIXME Stop streaming after a while */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) pr_err_ratelimited("isoc_handler without available buffer!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) goto resubmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) fb = list_first_entry(&dev->sio_avail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct stk_sio_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) fill = fb->buffer + fb->v4lbuf.bytesused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) for (i = 0; i < urb->number_of_packets; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (urb->iso_frame_desc[i].status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (urb->iso_frame_desc[i].status != -EXDEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) pr_err("Frame %d has error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) i, urb->iso_frame_desc[i].status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) framelen = urb->iso_frame_desc[i].actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (framelen <= 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) continue; /* no data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * we found something informational from there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * the isoc frames have to type of headers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * type1: 00 xx 00 00 or 20 xx 00 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * type2: 80 xx 00 00 00 00 00 00 or a0 xx 00 00 00 00 00 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * xx is a sequencer which has never been seen over 0x3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * imho data written down looks like bayer, i see similarities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * after every 640 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (*iso_buf & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) framelen -= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) iso_buf += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* This marks a new frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (fb->v4lbuf.bytesused != 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) && fb->v4lbuf.bytesused != dev->frame_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) pr_err_ratelimited("frame %d, bytesused=%d, skipping\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) i, fb->v4lbuf.bytesused);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) fb->v4lbuf.bytesused = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) fill = fb->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) } else if (fb->v4lbuf.bytesused == dev->frame_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (list_is_singular(&dev->sio_avail)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Always reuse the last buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) fb->v4lbuf.bytesused = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) fill = fb->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) list_move_tail(dev->sio_avail.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) &dev->sio_full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) wake_up(&dev->wait_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) fb = list_first_entry(&dev->sio_avail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct stk_sio_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) fb->v4lbuf.bytesused = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) fill = fb->buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) framelen -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) iso_buf += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* Our buffer is full !!! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (framelen + fb->v4lbuf.bytesused > dev->frame_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) pr_err_ratelimited("Frame buffer overflow, lost sync\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /*FIXME Do something here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) spin_unlock_irqrestore(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) memcpy(fill, iso_buf, framelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) spin_lock_irqsave(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) fill += framelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* New size of our buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) fb->v4lbuf.bytesused += framelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) resubmit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) spin_unlock_irqrestore(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) urb->dev = dev->udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) ret = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) pr_err("Error (%d) re-submitting urb in stk_isoc_handler\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* -------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static int stk_prepare_iso(struct stk_camera *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) void *kbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct usb_device *udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) udev = dev->udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (dev->isobufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) pr_err("isobufs already allocated. Bad\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) dev->isobufs = kcalloc(MAX_ISO_BUFS, sizeof(*dev->isobufs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (dev->isobufs == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) pr_err("Unable to allocate iso buffers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) for (i = 0; i < MAX_ISO_BUFS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (dev->isobufs[i].data == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) kbuf = kzalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (kbuf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) pr_err("Failed to allocate iso buffer %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) goto isobufs_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) dev->isobufs[i].data = kbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) pr_err("isobuf data already allocated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (dev->isobufs[i].urb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) urb = usb_alloc_urb(ISO_FRAMES_PER_DESC, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (urb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) goto isobufs_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) dev->isobufs[i].urb = urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) pr_err("Killing URB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) usb_kill_urb(dev->isobufs[i].urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) urb = dev->isobufs[i].urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) urb->interval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) urb->dev = udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) urb->pipe = usb_rcvisocpipe(udev, dev->isoc_ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) urb->transfer_flags = URB_ISO_ASAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) urb->transfer_buffer = dev->isobufs[i].data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) urb->transfer_buffer_length = ISO_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) urb->complete = stk_isoc_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) urb->context = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) urb->start_frame = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) urb->number_of_packets = ISO_FRAMES_PER_DESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) urb->iso_frame_desc[j].length = ISO_MAX_FRAME_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) set_memallocd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) isobufs_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) for (i = 0; i < MAX_ISO_BUFS && dev->isobufs[i].data; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) kfree(dev->isobufs[i].data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) for (i = 0; i < MAX_ISO_BUFS && dev->isobufs[i].urb; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) usb_free_urb(dev->isobufs[i].urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) kfree(dev->isobufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) dev->isobufs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) static void stk_clean_iso(struct stk_camera *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (dev == NULL || dev->isobufs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) for (i = 0; i < MAX_ISO_BUFS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) urb = dev->isobufs[i].urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (atomic_read(&dev->urbs_used) && is_present(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) usb_kill_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) kfree(dev->isobufs[i].data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) kfree(dev->isobufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) dev->isobufs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) unset_memallocd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int stk_setup_siobuf(struct stk_camera *dev, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct stk_sio_buffer *buf = dev->sio_bufs + index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) INIT_LIST_HEAD(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) buf->v4lbuf.length = PAGE_ALIGN(dev->frame_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) buf->buffer = vmalloc_user(buf->v4lbuf.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (buf->buffer == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) buf->mapcount = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) buf->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) buf->v4lbuf.index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) buf->v4lbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) buf->v4lbuf.flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) buf->v4lbuf.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) buf->v4lbuf.memory = V4L2_MEMORY_MMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) buf->v4lbuf.m.offset = 2*index*buf->v4lbuf.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int stk_free_sio_buffers(struct stk_camera *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) int nbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (dev->n_sbufs == 0 || dev->sio_bufs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * If any buffers are mapped, we cannot free them at all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) for (i = 0; i < dev->n_sbufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (dev->sio_bufs[i].mapcount > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * OK, let's do it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) spin_lock_irqsave(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) INIT_LIST_HEAD(&dev->sio_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) INIT_LIST_HEAD(&dev->sio_full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) nbufs = dev->n_sbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) dev->n_sbufs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) spin_unlock_irqrestore(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) for (i = 0; i < nbufs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) vfree(dev->sio_bufs[i].buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) kfree(dev->sio_bufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) dev->sio_bufs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static int stk_prepare_sio_buffers(struct stk_camera *dev, unsigned n_sbufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (dev->sio_bufs != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) pr_err("sio_bufs already allocated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dev->sio_bufs = kcalloc(n_sbufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) sizeof(struct stk_sio_buffer),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (dev->sio_bufs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) for (i = 0; i < n_sbufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (stk_setup_siobuf(dev, i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return (dev->n_sbufs > 1 ? 0 : -ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) dev->n_sbufs = i+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static int stk_allocate_buffers(struct stk_camera *dev, unsigned n_sbufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) err = stk_prepare_iso(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) stk_clean_iso(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) err = stk_prepare_sio_buffers(dev, n_sbufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) stk_free_sio_buffers(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static void stk_free_buffers(struct stk_camera *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) stk_clean_iso(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) stk_free_sio_buffers(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* -------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* v4l file operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static int v4l_stk_open(struct file *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct stk_camera *dev = video_drvdata(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (dev == NULL || !is_present(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (mutex_lock_interruptible(&dev->lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) if (!dev->first_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) stk_camera_write_reg(dev, 0x0, 0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dev->first_init = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) err = v4l2_fh_open(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) usb_autopm_get_interface(dev->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) static int v4l_stk_release(struct file *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct stk_camera *dev = video_drvdata(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) mutex_lock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (dev->owner == fp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) stk_stop_stream(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) stk_free_buffers(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) stk_camera_write_reg(dev, 0x0, 0x49); /* turn off the LED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) unset_initialised(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) dev->owner = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) usb_autopm_put_interface(dev->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return v4l2_fh_release(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static ssize_t stk_read(struct file *fp, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) size_t count, loff_t *f_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct stk_sio_buffer *sbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct stk_camera *dev = video_drvdata(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (!is_present(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (dev->owner && (!dev->reading || dev->owner != fp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) dev->owner = fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (!is_streaming(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (stk_initialise(dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) || stk_allocate_buffers(dev, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) || stk_start_stream(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) dev->reading = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) spin_lock_irqsave(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) for (i = 0; i < dev->n_sbufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) list_add_tail(&dev->sio_bufs[i].list, &dev->sio_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dev->sio_bufs[i].v4lbuf.flags = V4L2_BUF_FLAG_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) spin_unlock_irqrestore(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (*f_pos == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (fp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ret = wait_event_interruptible(dev->wait_frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) !list_empty(&dev->sio_full) || !is_present(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (!is_present(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (count + *f_pos > dev->frame_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) count = dev->frame_size - *f_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) spin_lock_irqsave(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (list_empty(&dev->sio_full)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) spin_unlock_irqrestore(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) pr_err("BUG: No siobufs ready\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) sbuf = list_first_entry(&dev->sio_full, struct stk_sio_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) spin_unlock_irqrestore(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (copy_to_user(buf, sbuf->buffer + *f_pos, count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) *f_pos += count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (*f_pos >= dev->frame_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) *f_pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) spin_lock_irqsave(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) list_move_tail(&sbuf->list, &dev->sio_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) spin_unlock_irqrestore(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) size_t count, loff_t *f_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct stk_camera *dev = video_drvdata(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (mutex_lock_interruptible(&dev->lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) ret = stk_read(fp, buf, count, f_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static __poll_t v4l_stk_poll(struct file *fp, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct stk_camera *dev = video_drvdata(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) __poll_t res = v4l2_ctrl_poll(fp, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) poll_wait(fp, &dev->wait_frame, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (!is_present(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return EPOLLERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (!list_empty(&dev->sio_full))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return res | EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static void stk_v4l_vm_open(struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct stk_sio_buffer *sbuf = vma->vm_private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) sbuf->mapcount++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) static void stk_v4l_vm_close(struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct stk_sio_buffer *sbuf = vma->vm_private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) sbuf->mapcount--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (sbuf->mapcount == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_MAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static const struct vm_operations_struct stk_v4l_vm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .open = stk_v4l_vm_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .close = stk_v4l_vm_close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static int v4l_stk_mmap(struct file *fp, struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct stk_camera *dev = video_drvdata(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct stk_sio_buffer *sbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) for (i = 0; i < dev->n_sbufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (dev->sio_bufs[i].v4lbuf.m.offset == offset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) sbuf = dev->sio_bufs + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (sbuf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ret = remap_vmalloc_range(vma, sbuf->buffer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) vma->vm_flags |= VM_DONTEXPAND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) vma->vm_private_data = sbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) vma->vm_ops = &stk_v4l_vm_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_MAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) stk_v4l_vm_open(vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /* v4l ioctl handlers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static int stk_vidioc_querycap(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) void *priv, struct v4l2_capability *cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct stk_camera *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) strscpy(cap->driver, "stk", sizeof(cap->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) strscpy(cap->card, "stk", sizeof(cap->card));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static int stk_vidioc_enum_input(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) void *priv, struct v4l2_input *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (input->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) strscpy(input->name, "Syntek USB Camera", sizeof(input->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) input->type = V4L2_INPUT_TYPE_CAMERA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) static int stk_vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) *i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) static int stk_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return i ? -EINVAL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) static int stk_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) struct stk_camera *dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) container_of(ctrl->handler, struct stk_camera, hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) case V4L2_CID_BRIGHTNESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return stk_sensor_set_brightness(dev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) case V4L2_CID_HFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (dmi_check_system(stk_upside_down_dmi_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) dev->vsettings.hflip = !ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) dev->vsettings.hflip = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) case V4L2_CID_VFLIP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (dmi_check_system(stk_upside_down_dmi_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) dev->vsettings.vflip = !ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) dev->vsettings.vflip = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) static int stk_vidioc_enum_fmt_vid_cap(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) void *priv, struct v4l2_fmtdesc *fmtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) switch (fmtd->index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) fmtd->pixelformat = V4L2_PIX_FMT_RGB565;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) fmtd->pixelformat = V4L2_PIX_FMT_RGB565X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) fmtd->pixelformat = V4L2_PIX_FMT_UYVY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) fmtd->pixelformat = V4L2_PIX_FMT_SBGGR8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) static struct stk_size {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) unsigned w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) unsigned h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) enum stk_mode m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) } stk_sizes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) { .w = 1280, .h = 1024, .m = MODE_SXGA, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) { .w = 640, .h = 480, .m = MODE_VGA, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) { .w = 352, .h = 288, .m = MODE_CIF, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) { .w = 320, .h = 240, .m = MODE_QVGA, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) { .w = 176, .h = 144, .m = MODE_QCIF, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) static int stk_vidioc_g_fmt_vid_cap(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) void *priv, struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct v4l2_pix_format *pix_format = &f->fmt.pix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct stk_camera *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) for (i = 0; i < ARRAY_SIZE(stk_sizes) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) stk_sizes[i].m != dev->vsettings.mode; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (i == ARRAY_SIZE(stk_sizes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) pr_err("ERROR: mode invalid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) pix_format->width = stk_sizes[i].w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) pix_format->height = stk_sizes[i].h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) pix_format->field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) pix_format->colorspace = V4L2_COLORSPACE_SRGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) pix_format->pixelformat = dev->vsettings.palette;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) pix_format->bytesperline = pix_format->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) pix_format->bytesperline = 2 * pix_format->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) pix_format->sizeimage = pix_format->bytesperline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * pix_format->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) static int stk_try_fmt_vid_cap(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct v4l2_format *fmtd, int *idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) switch (fmtd->fmt.pix.pixelformat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) case V4L2_PIX_FMT_RGB565:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) case V4L2_PIX_FMT_RGB565X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) case V4L2_PIX_FMT_UYVY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) case V4L2_PIX_FMT_YUYV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) case V4L2_PIX_FMT_SBGGR8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) for (i = 1; i < ARRAY_SIZE(stk_sizes); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (fmtd->fmt.pix.width > stk_sizes[i].w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (i == ARRAY_SIZE(stk_sizes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) || (abs(fmtd->fmt.pix.width - stk_sizes[i-1].w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) < abs(fmtd->fmt.pix.width - stk_sizes[i].w))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) fmtd->fmt.pix.height = stk_sizes[i-1].h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) fmtd->fmt.pix.width = stk_sizes[i-1].w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) *idx = i - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) fmtd->fmt.pix.height = stk_sizes[i].h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) fmtd->fmt.pix.width = stk_sizes[i].w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) *idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) fmtd->fmt.pix.field = V4L2_FIELD_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) fmtd->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (fmtd->fmt.pix.pixelformat == V4L2_PIX_FMT_SBGGR8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) fmtd->fmt.pix.bytesperline = fmtd->fmt.pix.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) fmtd->fmt.pix.bytesperline = 2 * fmtd->fmt.pix.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) fmtd->fmt.pix.sizeimage = fmtd->fmt.pix.bytesperline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * fmtd->fmt.pix.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) static int stk_vidioc_try_fmt_vid_cap(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) void *priv, struct v4l2_format *fmtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) return stk_try_fmt_vid_cap(filp, fmtd, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) static int stk_setup_format(struct stk_camera *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) int depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) depth = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) depth = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) while (i < ARRAY_SIZE(stk_sizes) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) stk_sizes[i].m != dev->vsettings.mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (i == ARRAY_SIZE(stk_sizes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) pr_err("Something is broken in %s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /* This registers controls some timings, not sure of what. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) stk_camera_write_reg(dev, 0x001b, 0x0e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (dev->vsettings.mode == MODE_SXGA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) stk_camera_write_reg(dev, 0x001c, 0x0e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) stk_camera_write_reg(dev, 0x001c, 0x46);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * Registers 0x0115 0x0114 are the size of each line (bytes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * regs 0x0117 0x0116 are the height of the image.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) stk_camera_write_reg(dev, 0x0115,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) ((stk_sizes[i].w * depth) >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) stk_camera_write_reg(dev, 0x0114,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) (stk_sizes[i].w * depth) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) stk_camera_write_reg(dev, 0x0117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) (stk_sizes[i].h >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) stk_camera_write_reg(dev, 0x0116,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) stk_sizes[i].h & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return stk_sensor_configure(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static int stk_vidioc_s_fmt_vid_cap(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) void *priv, struct v4l2_format *fmtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) struct stk_camera *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (!is_present(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (is_streaming(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (dev->owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) ret = stk_try_fmt_vid_cap(filp, fmtd, &idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) dev->vsettings.palette = fmtd->fmt.pix.pixelformat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) stk_free_buffers(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) dev->frame_size = fmtd->fmt.pix.sizeimage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) dev->vsettings.mode = stk_sizes[idx].m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) stk_initialise(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return stk_setup_format(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) static int stk_vidioc_reqbufs(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) void *priv, struct v4l2_requestbuffers *rb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct stk_camera *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (dev == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (rb->memory != V4L2_MEMORY_MMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (is_streaming(dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) || (dev->owner && dev->owner != filp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) stk_free_buffers(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (rb->count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) stk_camera_write_reg(dev, 0x0, 0x49); /* turn off the LED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) unset_initialised(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) dev->owner = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) dev->owner = filp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /*FIXME If they ask for zero, we must stop streaming and free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (rb->count < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) rb->count = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) /* Arbitrary limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) else if (rb->count > 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) rb->count = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) stk_allocate_buffers(dev, rb->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) rb->count = dev->n_sbufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) static int stk_vidioc_querybuf(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) void *priv, struct v4l2_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) struct stk_camera *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) struct stk_sio_buffer *sbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) if (buf->index >= dev->n_sbufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) sbuf = dev->sio_bufs + buf->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) *buf = sbuf->v4lbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static int stk_vidioc_qbuf(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) void *priv, struct v4l2_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct stk_camera *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct stk_sio_buffer *sbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (buf->memory != V4L2_MEMORY_MMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (buf->index >= dev->n_sbufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) sbuf = dev->sio_bufs + buf->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) spin_lock_irqsave(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) list_add_tail(&sbuf->list, &dev->sio_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) *buf = sbuf->v4lbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) spin_unlock_irqrestore(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static int stk_vidioc_dqbuf(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) void *priv, struct v4l2_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) struct stk_camera *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct stk_sio_buffer *sbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (!is_streaming(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (filp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return -EWOULDBLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) ret = wait_event_interruptible(dev->wait_frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) !list_empty(&dev->sio_full) || !is_present(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (!is_present(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) spin_lock_irqsave(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) sbuf = list_first_entry(&dev->sio_full, struct stk_sio_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) list_del_init(&sbuf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) spin_unlock_irqrestore(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) sbuf->v4lbuf.flags &= ~V4L2_BUF_FLAG_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) sbuf->v4lbuf.flags |= V4L2_BUF_FLAG_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) sbuf->v4lbuf.sequence = ++dev->sequence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) v4l2_buffer_set_timestamp(&sbuf->v4lbuf, ktime_get_ns());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) *buf = sbuf->v4lbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) static int stk_vidioc_streamon(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) void *priv, enum v4l2_buf_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct stk_camera *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (is_streaming(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (dev->sio_bufs == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) dev->sequence = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return stk_start_stream(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static int stk_vidioc_streamoff(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) void *priv, enum v4l2_buf_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct stk_camera *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) stk_stop_stream(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) spin_lock_irqsave(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) INIT_LIST_HEAD(&dev->sio_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) INIT_LIST_HEAD(&dev->sio_full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) for (i = 0; i < dev->n_sbufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) INIT_LIST_HEAD(&dev->sio_bufs[i].list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) dev->sio_bufs[i].v4lbuf.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) spin_unlock_irqrestore(&dev->spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static int stk_vidioc_g_parm(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) void *priv, struct v4l2_streamparm *sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) /*FIXME This is not correct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) sp->parm.capture.timeperframe.numerator = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) sp->parm.capture.timeperframe.denominator = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) sp->parm.capture.readbuffers = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) static int stk_vidioc_enum_framesizes(struct file *filp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) void *priv, struct v4l2_frmsizeenum *frms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (frms->index >= ARRAY_SIZE(stk_sizes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) switch (frms->pixel_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) case V4L2_PIX_FMT_RGB565:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) case V4L2_PIX_FMT_RGB565X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) case V4L2_PIX_FMT_UYVY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) case V4L2_PIX_FMT_YUYV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) case V4L2_PIX_FMT_SBGGR8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) frms->type = V4L2_FRMSIZE_TYPE_DISCRETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) frms->discrete.width = stk_sizes[frms->index].w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) frms->discrete.height = stk_sizes[frms->index].h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) default: return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static const struct v4l2_ctrl_ops stk_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) .s_ctrl = stk_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) static const struct v4l2_file_operations v4l_stk_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) .open = v4l_stk_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) .release = v4l_stk_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) .read = v4l_stk_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) .poll = v4l_stk_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) .mmap = v4l_stk_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) .unlocked_ioctl = video_ioctl2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) .vidioc_querycap = stk_vidioc_querycap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) .vidioc_enum_fmt_vid_cap = stk_vidioc_enum_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) .vidioc_try_fmt_vid_cap = stk_vidioc_try_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) .vidioc_s_fmt_vid_cap = stk_vidioc_s_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) .vidioc_g_fmt_vid_cap = stk_vidioc_g_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) .vidioc_enum_input = stk_vidioc_enum_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .vidioc_s_input = stk_vidioc_s_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) .vidioc_g_input = stk_vidioc_g_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .vidioc_reqbufs = stk_vidioc_reqbufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) .vidioc_querybuf = stk_vidioc_querybuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .vidioc_qbuf = stk_vidioc_qbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) .vidioc_dqbuf = stk_vidioc_dqbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) .vidioc_streamon = stk_vidioc_streamon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) .vidioc_streamoff = stk_vidioc_streamoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) .vidioc_g_parm = stk_vidioc_g_parm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) .vidioc_enum_framesizes = stk_vidioc_enum_framesizes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) .vidioc_log_status = v4l2_ctrl_log_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) static void stk_v4l_dev_release(struct video_device *vd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) struct stk_camera *dev = vdev_to_camera(vd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (dev->sio_bufs != NULL || dev->isobufs != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) pr_err("We are leaking memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) usb_put_intf(dev->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) static const struct video_device stk_v4l_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) .name = "stkwebcam",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) .fops = &v4l_stk_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .ioctl_ops = &v4l_stk_ioctl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) .release = stk_v4l_dev_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static int stk_register_video_device(struct stk_camera *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) dev->vdev = stk_v4l_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) dev->vdev.lock = &dev->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) dev->vdev.v4l2_dev = &dev->v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) dev->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) V4L2_CAP_STREAMING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) video_set_drvdata(&dev->vdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) err = video_register_device(&dev->vdev, VFL_TYPE_VIDEO, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) pr_err("v4l registration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) pr_info("Syntek USB2.0 Camera is now controlling device %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) video_device_node_name(&dev->vdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) /* USB Stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) static int stk_camera_probe(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) const struct usb_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) struct v4l2_ctrl_handler *hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct stk_camera *dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct usb_device *udev = interface_to_usbdev(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) struct usb_host_interface *iface_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct usb_endpoint_descriptor *endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) dev = kzalloc(sizeof(struct stk_camera), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) if (dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) pr_err("Out of memory !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) err = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) dev_err(&udev->dev, "couldn't register v4l2_device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) hdl = &dev->hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) v4l2_ctrl_handler_init(hdl, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) v4l2_ctrl_new_std(hdl, &stk_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) V4L2_CID_BRIGHTNESS, 0, 0xff, 0x1, 0x60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) v4l2_ctrl_new_std(hdl, &stk_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) V4L2_CID_HFLIP, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) v4l2_ctrl_new_std(hdl, &stk_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) V4L2_CID_VFLIP, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (hdl->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) err = hdl->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) dev_err(&udev->dev, "couldn't register control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) dev->v4l2_dev.ctrl_handler = hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) spin_lock_init(&dev->spinlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) mutex_init(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) init_waitqueue_head(&dev->wait_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) dev->first_init = 1; /* webcam LED management */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) dev->udev = udev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) dev->interface = interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) usb_get_intf(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (hflip != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) dev->vsettings.hflip = hflip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) else if (dmi_check_system(stk_upside_down_dmi_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) dev->vsettings.hflip = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) dev->vsettings.hflip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (vflip != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) dev->vsettings.vflip = vflip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) else if (dmi_check_system(stk_upside_down_dmi_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) dev->vsettings.vflip = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) dev->vsettings.vflip = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) dev->n_sbufs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) set_present(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) /* Set up the endpoint information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) * use only the first isoc-in endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) * for the current alternate setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) iface_desc = interface->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) endpoint = &iface_desc->endpoint[i].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (!dev->isoc_ep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) && usb_endpoint_is_isoc_in(endpoint)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) /* we found an isoc in endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) dev->isoc_ep = usb_endpoint_num(endpoint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) if (!dev->isoc_ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) pr_err("Could not find isoc-in endpoint\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) goto error_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) dev->vsettings.palette = V4L2_PIX_FMT_RGB565;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) dev->vsettings.mode = MODE_VGA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) dev->frame_size = 640 * 480 * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) INIT_LIST_HEAD(&dev->sio_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) INIT_LIST_HEAD(&dev->sio_full);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) usb_set_intfdata(interface, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) err = stk_register_video_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) goto error_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) error_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) usb_put_intf(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) v4l2_ctrl_handler_free(hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) v4l2_device_unregister(&dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) static void stk_camera_disconnect(struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) struct stk_camera *dev = usb_get_intfdata(interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) usb_set_intfdata(interface, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) unset_present(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) wake_up_interruptible(&dev->wait_frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) pr_info("Syntek USB2.0 Camera release resources device %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) video_device_node_name(&dev->vdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) video_unregister_device(&dev->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) v4l2_ctrl_handler_free(&dev->hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) v4l2_device_unregister(&dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) static int stk_camera_suspend(struct usb_interface *intf, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) struct stk_camera *dev = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (is_streaming(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) stk_stop_stream(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) /* yes, this is ugly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) set_streaming(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) static int stk_camera_resume(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct stk_camera *dev = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) if (!is_initialised(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) unset_initialised(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) stk_initialise(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) stk_camera_write_reg(dev, 0x0, 0x49);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) stk_setup_format(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (is_streaming(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) stk_start_stream(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) static struct usb_driver stk_camera_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) .name = "stkwebcam",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) .probe = stk_camera_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) .disconnect = stk_camera_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) .id_table = stkwebcam_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) .suspend = stk_camera_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) .resume = stk_camera_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) module_usb_driver(stk_camera_driver);