Path: blob/master/drivers/media/video/cx23885/cx23885-ioctl.c
17892 views
/*1* Driver for the Conexant CX23885/7/8 PCIe bridge2*3* Various common ioctl() support functions4*5* Copyright (c) 2009 Andy Walls <[email protected]>6*7* This program is free software; you can redistribute it and/or modify8* it under the terms of the GNU General Public License as published by9* the Free Software Foundation; either version 2 of the License, or10* (at your option) any later version.11*12* This program is distributed in the hope that it will be useful,13* but WITHOUT ANY WARRANTY; without even the implied warranty of14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15*16* GNU General Public License for more details.17*18* You should have received a copy of the GNU General Public License19* along with this program; if not, write to the Free Software20* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.21*/2223#include "cx23885.h"24#include <media/v4l2-chip-ident.h>2526int cx23885_g_chip_ident(struct file *file, void *fh,27struct v4l2_dbg_chip_ident *chip)28{29struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;30int err = 0;31u8 rev;3233chip->ident = V4L2_IDENT_NONE;34chip->revision = 0;35switch (chip->match.type) {36case V4L2_CHIP_MATCH_HOST:37switch (chip->match.addr) {38case 0:39rev = cx_read(RDR_CFG2) & 0xff;40switch (dev->pci->device) {41case 0x8852:42/* rev 0x04 could be '885 or '888. Pick '888. */43if (rev == 0x04)44chip->ident = V4L2_IDENT_CX23888;45else46chip->ident = V4L2_IDENT_CX23885;47break;48case 0x8880:49if (rev == 0x0e || rev == 0x0f)50chip->ident = V4L2_IDENT_CX23887;51else52chip->ident = V4L2_IDENT_CX23888;53break;54default:55chip->ident = V4L2_IDENT_UNKNOWN;56break;57}58chip->revision = (dev->pci->device << 16) | (rev << 8) |59(dev->hwrevision & 0xff);60break;61case 1:62if (dev->v4l_device != NULL) {63chip->ident = V4L2_IDENT_CX23417;64chip->revision = 0;65}66break;67case 2:68/*69* The integrated IR controller on the CX23888 is70* host chip 2. It may not be used/initialized or sd_ir71* may be pointing at the cx25840 subdevice for the72* IR controller on the CX23885. Thus we find it73* without using the dev->sd_ir pointer.74*/75call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident,76chip);77break;78default:79err = -EINVAL; /* per V4L2 spec */80break;81}82break;83case V4L2_CHIP_MATCH_I2C_DRIVER:84/* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */85call_all(dev, core, g_chip_ident, chip);86break;87case V4L2_CHIP_MATCH_I2C_ADDR:88/*89* We could return V4L2_IDENT_UNKNOWN, but we don't do the work90* to look if a chip is at the address with no driver. That's a91* dangerous thing to do with EEPROMs anyway.92*/93call_all(dev, core, g_chip_ident, chip);94break;95default:96err = -EINVAL;97break;98}99return err;100}101102#ifdef CONFIG_VIDEO_ADV_DEBUG103static int cx23885_g_host_register(struct cx23885_dev *dev,104struct v4l2_dbg_register *reg)105{106if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))107return -EINVAL;108109reg->size = 4;110reg->val = cx_read(reg->reg);111return 0;112}113114static int cx23417_g_register(struct cx23885_dev *dev,115struct v4l2_dbg_register *reg)116{117u32 value;118119if (dev->v4l_device == NULL)120return -EINVAL;121122if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)123return -EINVAL;124125if (mc417_register_read(dev, (u16) reg->reg, &value))126return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */127128reg->size = 4;129reg->val = value;130return 0;131}132133int cx23885_g_register(struct file *file, void *fh,134struct v4l2_dbg_register *reg)135{136struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;137138if (!capable(CAP_SYS_ADMIN))139return -EPERM;140141if (reg->match.type == V4L2_CHIP_MATCH_HOST) {142switch (reg->match.addr) {143case 0:144return cx23885_g_host_register(dev, reg);145case 1:146return cx23417_g_register(dev, reg);147default:148break;149}150}151152/* FIXME - any error returns should not be ignored */153call_all(dev, core, g_register, reg);154return 0;155}156157static int cx23885_s_host_register(struct cx23885_dev *dev,158struct v4l2_dbg_register *reg)159{160if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))161return -EINVAL;162163reg->size = 4;164cx_write(reg->reg, reg->val);165return 0;166}167168static int cx23417_s_register(struct cx23885_dev *dev,169struct v4l2_dbg_register *reg)170{171if (dev->v4l_device == NULL)172return -EINVAL;173174if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)175return -EINVAL;176177if (mc417_register_write(dev, (u16) reg->reg, (u32) reg->val))178return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */179180reg->size = 4;181return 0;182}183184int cx23885_s_register(struct file *file, void *fh,185struct v4l2_dbg_register *reg)186{187struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev;188189if (!capable(CAP_SYS_ADMIN))190return -EPERM;191192if (reg->match.type == V4L2_CHIP_MATCH_HOST) {193switch (reg->match.addr) {194case 0:195return cx23885_s_host_register(dev, reg);196case 1:197return cx23417_s_register(dev, reg);198default:199break;200}201}202203/* FIXME - any error returns should not be ignored */204call_all(dev, core, s_register, reg);205return 0;206}207#endif208209210