Path: blob/master/drivers/media/video/hdpvr/hdpvr-control.c
17628 views
/*1* Hauppauge HD PVR USB driver - video 4 linux 2 interface2*3* Copyright (C) 2008 Janne Grunau ([email protected])4*5* This program is free software; you can redistribute it and/or6* modify it under the terms of the GNU General Public License as7* published by the Free Software Foundation, version 2.8*9*/1011#include <linux/kernel.h>12#include <linux/errno.h>13#include <linux/init.h>14#include <linux/slab.h>15#include <linux/module.h>16#include <linux/usb.h>17#include <linux/mutex.h>1819#include <linux/videodev2.h>2021#include <media/v4l2-common.h>2223#include "hdpvr.h"242526int hdpvr_config_call(struct hdpvr_device *dev, uint value, u8 valbuf)27{28int ret;29char request_type = 0x38, snd_request = 0x01;3031mutex_lock(&dev->usbc_mutex);32dev->usbc_buf[0] = valbuf;33ret = usb_control_msg(dev->udev,34usb_sndctrlpipe(dev->udev, 0),35snd_request, 0x00 | request_type,36value, CTRL_DEFAULT_INDEX,37dev->usbc_buf, 1, 10000);3839mutex_unlock(&dev->usbc_mutex);40v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,41"config call request for value 0x%x returned %d\n", value,42ret);4344return ret < 0 ? ret : 0;45}4647struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)48{49struct hdpvr_video_info *vidinf = NULL;50#ifdef HDPVR_DEBUG51char print_buf[15];52#endif53int ret;5455vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);56if (!vidinf) {57v4l2_err(&dev->v4l2_dev, "out of memory\n");58goto err;59}6061mutex_lock(&dev->usbc_mutex);62ret = usb_control_msg(dev->udev,63usb_rcvctrlpipe(dev->udev, 0),640x81, 0x80 | 0x38,650x1400, 0x0003,66dev->usbc_buf, 5,671000);68if (ret == 5) {69vidinf->width = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];70vidinf->height = dev->usbc_buf[3] << 8 | dev->usbc_buf[2];71vidinf->fps = dev->usbc_buf[4];72}7374#ifdef HDPVR_DEBUG75if (hdpvr_debug & MSG_INFO) {76hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf,77sizeof(print_buf), 0);78v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,79"get video info returned: %d, %s\n", ret, print_buf);80}81#endif82mutex_unlock(&dev->usbc_mutex);8384if (!vidinf->width || !vidinf->height || !vidinf->fps) {85kfree(vidinf);86vidinf = NULL;87}88err:89return vidinf;90}9192int get_input_lines_info(struct hdpvr_device *dev)93{94#ifdef HDPVR_DEBUG95char print_buf[9];96#endif97int ret, lines;9899mutex_lock(&dev->usbc_mutex);100ret = usb_control_msg(dev->udev,101usb_rcvctrlpipe(dev->udev, 0),1020x81, 0x80 | 0x38,1030x1800, 0x0003,104dev->usbc_buf, 3,1051000);106107#ifdef HDPVR_DEBUG108if (hdpvr_debug & MSG_INFO) {109hex_dump_to_buffer(dev->usbc_buf, 3, 16, 1, print_buf,110sizeof(print_buf), 0);111v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,112"get input lines info returned: %d, %s\n", ret,113print_buf);114}115#endif116lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];117mutex_unlock(&dev->usbc_mutex);118return lines;119}120121122int hdpvr_set_bitrate(struct hdpvr_device *dev)123{124int ret;125126mutex_lock(&dev->usbc_mutex);127memset(dev->usbc_buf, 0, 4);128dev->usbc_buf[0] = dev->options.bitrate;129dev->usbc_buf[2] = dev->options.peak_bitrate;130131ret = usb_control_msg(dev->udev,132usb_sndctrlpipe(dev->udev, 0),1330x01, 0x38, CTRL_BITRATE_VALUE,134CTRL_DEFAULT_INDEX, dev->usbc_buf, 4, 1000);135mutex_unlock(&dev->usbc_mutex);136137return ret;138}139140int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,141enum v4l2_mpeg_audio_encoding codec)142{143int ret = 0;144145if (dev->flags & HDPVR_FLAG_AC3_CAP) {146mutex_lock(&dev->usbc_mutex);147memset(dev->usbc_buf, 0, 2);148dev->usbc_buf[0] = input;149if (codec == V4L2_MPEG_AUDIO_ENCODING_AAC)150dev->usbc_buf[1] = 0;151else if (codec == V4L2_MPEG_AUDIO_ENCODING_AC3)152dev->usbc_buf[1] = 1;153else {154mutex_unlock(&dev->usbc_mutex);155v4l2_err(&dev->v4l2_dev, "invalid audio codec %d\n",156codec);157ret = -EINVAL;158goto error;159}160161ret = usb_control_msg(dev->udev,162usb_sndctrlpipe(dev->udev, 0),1630x01, 0x38, CTRL_AUDIO_INPUT_VALUE,164CTRL_DEFAULT_INDEX, dev->usbc_buf, 2,1651000);166mutex_unlock(&dev->usbc_mutex);167if (ret == 2)168ret = 0;169} else170ret = hdpvr_config_call(dev, CTRL_AUDIO_INPUT_VALUE, input);171error:172return ret;173}174175int hdpvr_set_options(struct hdpvr_device *dev)176{177hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std);178179hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE,180dev->options.video_input+1);181182hdpvr_set_audio(dev, dev->options.audio_input+1,183dev->options.audio_codec);184185hdpvr_set_bitrate(dev);186hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,187dev->options.bitrate_mode);188hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode);189190hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness);191hdpvr_config_call(dev, CTRL_CONTRAST, dev->options.contrast);192hdpvr_config_call(dev, CTRL_HUE, dev->options.hue);193hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation);194hdpvr_config_call(dev, CTRL_SHARPNESS, dev->options.sharpness);195196return 0;197}198199200