return count;
}
-static ssize_t video_type_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- return -EPERM;
-}
-
-static ssize_t video_type_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct solo_dev *solo_dev =
- container_of(dev, struct solo_dev, dev);
-
- return sprintf(buf, "%s", solo_dev->video_type ==
- SOLO_VO_FMT_TYPE_NTSC ? "NTSC" : "PAL");
-}
-
static ssize_t p2m_timeouts_show(struct device *dev,
struct device_attribute *attr,
char *buf)
static const struct device_attribute solo_dev_attrs[] = {
__ATTR(eeprom, 0640, eeprom_show, eeprom_store),
- __ATTR(video_type, 0644, video_type_show, video_type_store),
__ATTR(p2m_timeout, 0644, p2m_timeout_show, p2m_timeout_store),
__ATTR_RO(p2m_timeouts),
__ATTR_RO(sdram_size),
#define SOLO_MOT_FLAG_SIZE 1024
#define SOLO_MOT_FLAG_AREA (SOLO_MOT_FLAG_SIZE * 16)
-static unsigned video_type;
-module_param(video_type, uint, 0644);
-MODULE_PARM_DESC(video_type, "video_type (0 = NTSC/Default, 1 = PAL)");
-
static void solo_vin_config(struct solo_dev *solo_dev)
{
solo_dev->vin_hstart = 8;
int i;
solo_dev->video_hsize = 704;
- if (video_type == 0) {
- solo_dev->video_type = SOLO_VO_FMT_TYPE_NTSC;
+ if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) {
solo_dev->video_vsize = 240;
solo_dev->fps = 30;
} else {
- solo_dev->video_type = SOLO_VO_FMT_TYPE_PAL;
solo_dev->video_vsize = 288;
solo_dev->fps = 25;
}
solo_reg_write(dev, SOLO_IRQ_MASK, dev->irq_mask);
}
-/* Init/exit routeines for subsystems */
+/* Init/exit routines for subsystems */
int solo_disp_init(struct solo_dev *solo_dev);
void solo_disp_exit(struct solo_dev *solo_dev);
struct solo_p2m_desc *desc, dma_addr_t desc_dma,
int desc_cnt);
+/* Global s_std ioctl */
+int solo_set_video_type(struct solo_dev *solo_dev, bool type);
+void solo_update_mode(struct solo_enc_dev *solo_enc);
+
/* Set the threshold for motion detection */
int solo_set_motion_threshold(struct solo_dev *solo_dev, u8 ch, u16 val);
int solo_set_motion_block(struct solo_dev *solo_dev, u8 ch, u16 val,
int i;
u8 value;
+ solo_dev->tw28_cnt = 0;
+
/* Detect techwell chip type(s) */
for (i = 0; i < solo_dev->nr_chans / 4; i++) {
value = solo_i2c_readbyte(solo_dev, SOLO_I2C_TW,
spin_unlock_irqrestore(&solo_enc->motion_lock, flags);
}
-static void solo_update_mode(struct solo_enc_dev *solo_enc)
+void solo_update_mode(struct solo_enc_dev *solo_enc)
{
struct solo_dev *solo_dev = solo_enc->solo_dev;
int vop_len;
snprintf(input->name, sizeof(input->name), "Encoder %d",
solo_enc->ch + 1);
input->type = V4L2_INPUT_TYPE_CAMERA;
-
- if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
- input->std = V4L2_STD_NTSC_M;
- else
- input->std = V4L2_STD_PAL_B;
+ input->std = solo_enc->vfd->tvnorms;
if (!tw28_get_video_status(solo_dev, solo_enc->ch))
input->status = V4L2_IN_ST_NO_SIGNAL;
return 0;
}
-static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id i)
+static int solo_enc_g_std(struct file *file, void *priv, v4l2_std_id *i)
{
+ struct solo_enc_dev *solo_enc = video_drvdata(file);
+ struct solo_dev *solo_dev = solo_enc->solo_dev;
+
+ if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
+ *i = V4L2_STD_NTSC_M;
+ else
+ *i = V4L2_STD_PAL;
return 0;
}
+static int solo_enc_s_std(struct file *file, void *priv, v4l2_std_id std)
+{
+ struct solo_enc_dev *solo_enc = video_drvdata(file);
+
+ return solo_set_video_type(solo_enc->solo_dev, std & V4L2_STD_PAL);
+}
+
static int solo_enum_framesizes(struct file *file, void *priv,
struct v4l2_frmsizeenum *fsize)
{
fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE;
+ fintv->stepwise.min.numerator = 1;
fintv->stepwise.min.denominator = solo_dev->fps;
- fintv->stepwise.min.numerator = 15;
+ fintv->stepwise.max.numerator = 15;
fintv->stepwise.max.denominator = solo_dev->fps;
- fintv->stepwise.max.numerator = 1;
fintv->stepwise.step.numerator = 1;
- fintv->stepwise.step.denominator = 1;
+ fintv->stepwise.step.denominator = solo_dev->fps;
return 0;
}
static const struct v4l2_ioctl_ops solo_enc_ioctl_ops = {
.vidioc_querycap = solo_enc_querycap,
.vidioc_s_std = solo_enc_s_std,
+ .vidioc_g_std = solo_enc_g_std,
/* Input callbacks */
.vidioc_enum_input = solo_enc_enum_input,
.vidioc_s_input = solo_enc_set_input,
.ioctl_ops = &solo_enc_ioctl_ops,
.minor = -1,
.release = video_device_release,
-
- .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_B,
- .current_norm = V4L2_STD_NTSC_M,
+ .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL,
};
static const struct v4l2_ctrl_ops solo_ctrl_ops = {
ret = vb2_queue_init(&solo_enc->vidq);
if (ret)
goto hdl_free;
- spin_lock(&solo_enc->av_lock);
solo_update_mode(solo_enc);
- spin_unlock(&solo_enc->av_lock);
spin_lock_init(&solo_enc->motion_lock);
}
input->type = V4L2_INPUT_TYPE_CAMERA;
-
- if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
- input->std = V4L2_STD_NTSC_M;
- else
- input->std = V4L2_STD_PAL_B;
-
+ input->std = solo_dev->vfd->tvnorms;
return 0;
}
return 0;
}
-static int solo_s_std(struct file *file, void *priv, v4l2_std_id i)
+static int solo_g_std(struct file *file, void *priv, v4l2_std_id *i)
{
+ struct solo_dev *solo_dev = video_drvdata(file);
+
+ if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC)
+ *i = V4L2_STD_NTSC_M;
+ else
+ *i = V4L2_STD_PAL;
return 0;
}
+int solo_set_video_type(struct solo_dev *solo_dev, bool type)
+{
+ int i;
+
+ /* Make sure all video nodes are idle */
+ if (vb2_is_busy(&solo_dev->vidq))
+ return -EBUSY;
+ for (i = 0; i < solo_dev->nr_chans; i++)
+ if (vb2_is_busy(&solo_dev->v4l2_enc[i]->vidq))
+ return -EBUSY;
+ solo_dev->video_type = type;
+ /* Reconfigure for the new standard */
+ solo_disp_init(solo_dev);
+ solo_enc_init(solo_dev);
+ solo_tw28_init(solo_dev);
+ for (i = 0; i < solo_dev->nr_chans; i++)
+ solo_update_mode(solo_dev->v4l2_enc[i]);
+ return solo_v4l2_set_ch(solo_dev, solo_dev->cur_disp_ch);
+}
+
+static int solo_s_std(struct file *file, void *priv, v4l2_std_id std)
+{
+ struct solo_dev *solo_dev = video_drvdata(file);
+
+ return solo_set_video_type(solo_dev, std & V4L2_STD_PAL);
+}
+
static int solo_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct solo_dev *solo_dev =
static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = {
.vidioc_querycap = solo_querycap,
.vidioc_s_std = solo_s_std,
+ .vidioc_g_std = solo_g_std,
/* Input callbacks */
.vidioc_enum_input = solo_enum_input,
.vidioc_s_input = solo_set_input,
.ioctl_ops = &solo_v4l2_ioctl_ops,
.minor = -1,
.release = video_device_release,
-
- .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_B,
- .current_norm = V4L2_STD_NTSC_M,
+ .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL,
};
static const struct v4l2_ctrl_ops solo_ctrl_ops = {