Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2fd78144 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB: ivtv: convert gpio subdev to new control framework

parent f687d19d
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -1386,6 +1386,7 @@ static void ivtv_remove(struct pci_dev *pdev)
	printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);
	printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);


	v4l2_device_unregister(&itv->v4l2_dev);
	v4l2_device_unregister(&itv->v4l2_dev);
	v4l2_ctrl_handler_free(&itv->hdl_gpio);
	kfree(itv);
	kfree(itv);
}
}


+1 −0
Original line number Original line Diff line number Diff line
@@ -632,6 +632,7 @@ struct ivtv {


	struct v4l2_device v4l2_dev;
	struct v4l2_device v4l2_dev;
	struct v4l2_subdev sd_gpio;	/* GPIO sub-device */
	struct v4l2_subdev sd_gpio;	/* GPIO sub-device */
	struct v4l2_ctrl_handler hdl_gpio;
	u16 instance;
	u16 instance;


	/* High-level state info */
	/* High-level state info */
+36 −41
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@
#include "ivtv-gpio.h"
#include "ivtv-gpio.h"
#include "tuner-xc2028.h"
#include "tuner-xc2028.h"
#include <media/tuner.h>
#include <media/tuner.h>
#include <media/v4l2-ctrls.h>


/*
/*
 * GPIO assignment of Yuan MPG600/MPG160
 * GPIO assignment of Yuan MPG600/MPG160
@@ -149,16 +150,10 @@ static inline struct ivtv *sd_to_ivtv(struct v4l2_subdev *sd)
	return container_of(sd, struct ivtv, sd_gpio);
	return container_of(sd, struct ivtv, sd_gpio);
}
}


static struct v4l2_queryctrl gpio_ctrl_mute = {
static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
	.id            = V4L2_CID_AUDIO_MUTE,
{
	.type          = V4L2_CTRL_TYPE_BOOLEAN,
	return &container_of(ctrl->handler, struct ivtv, hdl_gpio)->sd_gpio;
	.name          = "Mute",
}
	.minimum       = 0,
	.maximum       = 1,
	.step          = 1,
	.default_value = 1,
	.flags         = 0,
};


static int subdev_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
static int subdev_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
{
{
@@ -262,41 +257,25 @@ static int subdev_s_audio_routing(struct v4l2_subdev *sd,
	return 0;
	return 0;
}
}


static int subdev_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int subdev_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct ivtv *itv = sd_to_ivtv(sd);
	u16 mask, data;

	if (ctrl->id != V4L2_CID_AUDIO_MUTE)
		return -EINVAL;
	mask = itv->card->gpio_audio_mute.mask;
	data = itv->card->gpio_audio_mute.mute;
	ctrl->value = (read_reg(IVTV_REG_GPIO_OUT) & mask) == data;
	return 0;
}

static int subdev_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
{
	struct v4l2_subdev *sd = to_sd(ctrl);
	struct ivtv *itv = sd_to_ivtv(sd);
	struct ivtv *itv = sd_to_ivtv(sd);
	u16 mask, data;
	u16 mask, data;


	if (ctrl->id != V4L2_CID_AUDIO_MUTE)
	switch (ctrl->id) {
		return -EINVAL;
	case V4L2_CID_AUDIO_MUTE:
		mask = itv->card->gpio_audio_mute.mask;
		mask = itv->card->gpio_audio_mute.mask;
	data = ctrl->value ? itv->card->gpio_audio_mute.mute : 0;
		data = ctrl->val ? itv->card->gpio_audio_mute.mute : 0;
		if (mask)
		if (mask)
		write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) | (data & mask), IVTV_REG_GPIO_OUT);
			write_reg((read_reg(IVTV_REG_GPIO_OUT) & ~mask) |
					(data & mask), IVTV_REG_GPIO_OUT);
		return 0;
		return 0;
	}
	}

static int subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
	if (qc->id != V4L2_CID_AUDIO_MUTE)
	return -EINVAL;
	return -EINVAL;
	*qc = gpio_ctrl_mute;
	return 0;
}
}



static int subdev_log_status(struct v4l2_subdev *sd)
static int subdev_log_status(struct v4l2_subdev *sd)
{
{
	struct ivtv *itv = sd_to_ivtv(sd);
	struct ivtv *itv = sd_to_ivtv(sd);
@@ -304,6 +283,7 @@ static int subdev_log_status(struct v4l2_subdev *sd)
	IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n",
	IVTV_INFO("GPIO status: DIR=0x%04x OUT=0x%04x IN=0x%04x\n",
			read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT),
			read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT),
			read_reg(IVTV_REG_GPIO_IN));
			read_reg(IVTV_REG_GPIO_IN));
	v4l2_ctrl_handler_log_status(&itv->hdl_gpio, sd->name);
	return 0;
	return 0;
}
}


@@ -327,11 +307,19 @@ static int subdev_s_video_routing(struct v4l2_subdev *sd,
	return 0;
	return 0;
}
}


static const struct v4l2_ctrl_ops gpio_ctrl_ops = {
	.s_ctrl = subdev_s_ctrl,
};

static const struct v4l2_subdev_core_ops subdev_core_ops = {
static const struct v4l2_subdev_core_ops subdev_core_ops = {
	.log_status = subdev_log_status,
	.log_status = subdev_log_status,
	.g_ctrl = subdev_g_ctrl,
	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
	.s_ctrl = subdev_s_ctrl,
	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
	.queryctrl = subdev_queryctrl,
	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
	.g_ctrl = v4l2_subdev_g_ctrl,
	.s_ctrl = v4l2_subdev_s_ctrl,
	.queryctrl = v4l2_subdev_queryctrl,
	.querymenu = v4l2_subdev_querymenu,
};
};


static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = {
static const struct v4l2_subdev_tuner_ops subdev_tuner_ops = {
@@ -375,5 +363,12 @@ int ivtv_gpio_init(struct ivtv *itv)
	v4l2_subdev_init(&itv->sd_gpio, &subdev_ops);
	v4l2_subdev_init(&itv->sd_gpio, &subdev_ops);
	snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name);
	snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name);
	itv->sd_gpio.grp_id = IVTV_HW_GPIO;
	itv->sd_gpio.grp_id = IVTV_HW_GPIO;
	v4l2_ctrl_handler_init(&itv->hdl_gpio, 1);
	v4l2_ctrl_new_std(&itv->hdl_gpio, &gpio_ctrl_ops,
			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
	if (itv->hdl_gpio.error)
		return itv->hdl_gpio.error;
	itv->sd_gpio.ctrl_handler = &itv->hdl_gpio;
	v4l2_ctrl_handler_setup(&itv->hdl_gpio);
	return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio);
	return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio);
}
}