18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Driver for the Conexant CX23885/7/8 PCIe bridge
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Various common ioctl() support functions
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci *  Copyright (c) 2009 Andy Walls <awalls@md.metrocast.net>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "cx23885.h"
118c2ecf20Sopenharmony_ci#include "cx23885-ioctl.h"
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#ifdef CONFIG_VIDEO_ADV_DEBUG
148c2ecf20Sopenharmony_ciint cx23885_g_chip_info(struct file *file, void *fh,
158c2ecf20Sopenharmony_ci			 struct v4l2_dbg_chip_info *chip)
168c2ecf20Sopenharmony_ci{
178c2ecf20Sopenharmony_ci	struct cx23885_dev *dev = video_drvdata(file);
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci	if (chip->match.addr > 1)
208c2ecf20Sopenharmony_ci		return -EINVAL;
218c2ecf20Sopenharmony_ci	if (chip->match.addr == 1) {
228c2ecf20Sopenharmony_ci		if (dev->v4l_device == NULL)
238c2ecf20Sopenharmony_ci			return -EINVAL;
248c2ecf20Sopenharmony_ci		strscpy(chip->name, "cx23417", sizeof(chip->name));
258c2ecf20Sopenharmony_ci	} else {
268c2ecf20Sopenharmony_ci		strscpy(chip->name, dev->v4l2_dev.name, sizeof(chip->name));
278c2ecf20Sopenharmony_ci	}
288c2ecf20Sopenharmony_ci	return 0;
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic int cx23417_g_register(struct cx23885_dev *dev,
328c2ecf20Sopenharmony_ci			      struct v4l2_dbg_register *reg)
338c2ecf20Sopenharmony_ci{
348c2ecf20Sopenharmony_ci	u32 value;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	if (dev->v4l_device == NULL)
378c2ecf20Sopenharmony_ci		return -EINVAL;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
408c2ecf20Sopenharmony_ci		return -EINVAL;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	if (mc417_register_read(dev, (u16) reg->reg, &value))
438c2ecf20Sopenharmony_ci		return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	reg->size = 4;
468c2ecf20Sopenharmony_ci	reg->val = value;
478c2ecf20Sopenharmony_ci	return 0;
488c2ecf20Sopenharmony_ci}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ciint cx23885_g_register(struct file *file, void *fh,
518c2ecf20Sopenharmony_ci		       struct v4l2_dbg_register *reg)
528c2ecf20Sopenharmony_ci{
538c2ecf20Sopenharmony_ci	struct cx23885_dev *dev = video_drvdata(file);
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	if (reg->match.addr > 1)
568c2ecf20Sopenharmony_ci		return -EINVAL;
578c2ecf20Sopenharmony_ci	if (reg->match.addr)
588c2ecf20Sopenharmony_ci		return cx23417_g_register(dev, reg);
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
618c2ecf20Sopenharmony_ci		return -EINVAL;
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	reg->size = 4;
648c2ecf20Sopenharmony_ci	reg->val = cx_read(reg->reg);
658c2ecf20Sopenharmony_ci	return 0;
668c2ecf20Sopenharmony_ci}
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistatic int cx23417_s_register(struct cx23885_dev *dev,
698c2ecf20Sopenharmony_ci			      const struct v4l2_dbg_register *reg)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	if (dev->v4l_device == NULL)
728c2ecf20Sopenharmony_ci		return -EINVAL;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000)
758c2ecf20Sopenharmony_ci		return -EINVAL;
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	if (mc417_register_write(dev, (u16) reg->reg, (u32) reg->val))
788c2ecf20Sopenharmony_ci		return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */
798c2ecf20Sopenharmony_ci	return 0;
808c2ecf20Sopenharmony_ci}
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ciint cx23885_s_register(struct file *file, void *fh,
838c2ecf20Sopenharmony_ci		       const struct v4l2_dbg_register *reg)
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	struct cx23885_dev *dev = video_drvdata(file);
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	if (reg->match.addr > 1)
888c2ecf20Sopenharmony_ci		return -EINVAL;
898c2ecf20Sopenharmony_ci	if (reg->match.addr)
908c2ecf20Sopenharmony_ci		return cx23417_s_register(dev, reg);
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0))
938c2ecf20Sopenharmony_ci		return -EINVAL;
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci	cx_write(reg->reg, reg->val);
968c2ecf20Sopenharmony_ci	return 0;
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci#endif
99