saa7134-empress.c revision b93a18d56057a6f8ccb79c5cd085dd31395331ff
1/* 2 * 3 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 20#include <linux/init.h> 21#include <linux/list.h> 22#include <linux/module.h> 23#include <linux/kernel.h> 24#include <linux/delay.h> 25 26#include "saa7134-reg.h" 27#include "saa7134.h" 28 29#include <media/saa6752hs.h> 30#include <media/v4l2-common.h> 31 32/* ------------------------------------------------------------------ */ 33 34MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 35MODULE_LICENSE("GPL"); 36 37static unsigned int empress_nr[] = {[0 ... (SAA7134_MAXBOARDS - 1)] = UNSET }; 38 39module_param_array(empress_nr, int, NULL, 0444); 40MODULE_PARM_DESC(empress_nr,"ts device number"); 41 42static unsigned int debug; 43module_param(debug, int, 0644); 44MODULE_PARM_DESC(debug,"enable debug messages"); 45 46#define dprintk(fmt, arg...) if (debug) \ 47 printk(KERN_DEBUG "%s/empress: " fmt, dev->name , ## arg) 48 49/* ------------------------------------------------------------------ */ 50 51static void ts_reset_encoder(struct saa7134_dev* dev) 52{ 53 if (!dev->empress_started) 54 return; 55 56 saa_writeb(SAA7134_SPECIAL_MODE, 0x00); 57 msleep(10); 58 saa_writeb(SAA7134_SPECIAL_MODE, 0x01); 59 msleep(100); 60 dev->empress_started = 0; 61} 62 63static int ts_init_encoder(struct saa7134_dev* dev) 64{ 65 u32 leading_null_bytes = 0; 66 67 /* If more cards start to need this, then this 68 should probably be added to the card definitions. */ 69 switch (dev->board) { 70 case SAA7134_BOARD_BEHOLD_M6: 71 case SAA7134_BOARD_BEHOLD_M63: 72 case SAA7134_BOARD_BEHOLD_M6_EXTRA: 73 leading_null_bytes = 1; 74 break; 75 } 76 ts_reset_encoder(dev); 77 saa_call_all(dev, core, init, leading_null_bytes); 78 dev->empress_started = 1; 79 return 0; 80} 81 82/* ------------------------------------------------------------------ */ 83 84static int ts_open(struct file *file) 85{ 86 struct video_device *vdev = video_devdata(file); 87 struct saa7134_dev *dev = video_drvdata(file); 88 int err; 89 90 dprintk("open dev=%s\n", video_device_node_name(vdev)); 91 err = -EBUSY; 92 if (!mutex_trylock(&dev->empress_tsq.vb_lock)) 93 return err; 94 if (atomic_read(&dev->empress_users)) 95 goto done; 96 97 /* Unmute audio */ 98 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, 99 saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); 100 101 atomic_inc(&dev->empress_users); 102 file->private_data = dev; 103 err = 0; 104 105done: 106 mutex_unlock(&dev->empress_tsq.vb_lock); 107 return err; 108} 109 110static int ts_release(struct file *file) 111{ 112 struct saa7134_dev *dev = file->private_data; 113 114 videobuf_stop(&dev->empress_tsq); 115 videobuf_mmap_free(&dev->empress_tsq); 116 117 /* stop the encoder */ 118 ts_reset_encoder(dev); 119 120 /* Mute audio */ 121 saa_writeb(SAA7134_AUDIO_MUTE_CTRL, 122 saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); 123 124 atomic_dec(&dev->empress_users); 125 126 return 0; 127} 128 129static ssize_t 130ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 131{ 132 struct saa7134_dev *dev = file->private_data; 133 134 if (!dev->empress_started) 135 ts_init_encoder(dev); 136 137 return videobuf_read_stream(&dev->empress_tsq, 138 data, count, ppos, 0, 139 file->f_flags & O_NONBLOCK); 140} 141 142static unsigned int 143ts_poll(struct file *file, struct poll_table_struct *wait) 144{ 145 struct saa7134_dev *dev = file->private_data; 146 147 return videobuf_poll_stream(file, &dev->empress_tsq, wait); 148} 149 150 151static int 152ts_mmap(struct file *file, struct vm_area_struct * vma) 153{ 154 struct saa7134_dev *dev = file->private_data; 155 156 return videobuf_mmap_mapper(&dev->empress_tsq, vma); 157} 158 159static int empress_enum_fmt_vid_cap(struct file *file, void *priv, 160 struct v4l2_fmtdesc *f) 161{ 162 if (f->index != 0) 163 return -EINVAL; 164 165 strlcpy(f->description, "MPEG TS", sizeof(f->description)); 166 f->pixelformat = V4L2_PIX_FMT_MPEG; 167 f->flags = V4L2_FMT_FLAG_COMPRESSED; 168 return 0; 169} 170 171static int empress_g_fmt_vid_cap(struct file *file, void *priv, 172 struct v4l2_format *f) 173{ 174 struct saa7134_dev *dev = file->private_data; 175 struct v4l2_mbus_framefmt mbus_fmt; 176 177 saa_call_all(dev, video, g_mbus_fmt, &mbus_fmt); 178 179 v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); 180 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 181 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; 182 f->fmt.pix.bytesperline = 0; 183 f->fmt.pix.priv = 0; 184 185 return 0; 186} 187 188static int empress_s_fmt_vid_cap(struct file *file, void *priv, 189 struct v4l2_format *f) 190{ 191 struct saa7134_dev *dev = file->private_data; 192 struct v4l2_mbus_framefmt mbus_fmt; 193 194 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); 195 saa_call_all(dev, video, s_mbus_fmt, &mbus_fmt); 196 v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); 197 198 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 199 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; 200 f->fmt.pix.bytesperline = 0; 201 f->fmt.pix.priv = 0; 202 203 return 0; 204} 205 206static int empress_try_fmt_vid_cap(struct file *file, void *priv, 207 struct v4l2_format *f) 208{ 209 struct saa7134_dev *dev = file->private_data; 210 struct v4l2_mbus_framefmt mbus_fmt; 211 212 v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); 213 saa_call_all(dev, video, try_mbus_fmt, &mbus_fmt); 214 v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); 215 216 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 217 f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; 218 f->fmt.pix.bytesperline = 0; 219 f->fmt.pix.priv = 0; 220 221 return 0; 222} 223 224static int empress_reqbufs(struct file *file, void *priv, 225 struct v4l2_requestbuffers *p) 226{ 227 struct saa7134_dev *dev = file->private_data; 228 229 return videobuf_reqbufs(&dev->empress_tsq, p); 230} 231 232static int empress_querybuf(struct file *file, void *priv, 233 struct v4l2_buffer *b) 234{ 235 struct saa7134_dev *dev = file->private_data; 236 237 return videobuf_querybuf(&dev->empress_tsq, b); 238} 239 240static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) 241{ 242 struct saa7134_dev *dev = file->private_data; 243 244 return videobuf_qbuf(&dev->empress_tsq, b); 245} 246 247static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) 248{ 249 struct saa7134_dev *dev = file->private_data; 250 251 return videobuf_dqbuf(&dev->empress_tsq, b, 252 file->f_flags & O_NONBLOCK); 253} 254 255static int empress_streamon(struct file *file, void *priv, 256 enum v4l2_buf_type type) 257{ 258 struct saa7134_dev *dev = file->private_data; 259 260 return videobuf_streamon(&dev->empress_tsq); 261} 262 263static int empress_streamoff(struct file *file, void *priv, 264 enum v4l2_buf_type type) 265{ 266 struct saa7134_dev *dev = file->private_data; 267 268 return videobuf_streamoff(&dev->empress_tsq); 269} 270 271static const struct v4l2_file_operations ts_fops = 272{ 273 .owner = THIS_MODULE, 274 .open = ts_open, 275 .release = ts_release, 276 .read = ts_read, 277 .poll = ts_poll, 278 .mmap = ts_mmap, 279 .ioctl = video_ioctl2, 280}; 281 282static const struct v4l2_ioctl_ops ts_ioctl_ops = { 283 .vidioc_querycap = saa7134_querycap, 284 .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, 285 .vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap, 286 .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, 287 .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, 288 .vidioc_reqbufs = empress_reqbufs, 289 .vidioc_querybuf = empress_querybuf, 290 .vidioc_qbuf = empress_qbuf, 291 .vidioc_dqbuf = empress_dqbuf, 292 .vidioc_streamon = empress_streamon, 293 .vidioc_streamoff = empress_streamoff, 294 .vidioc_g_frequency = saa7134_g_frequency, 295 .vidioc_s_frequency = saa7134_s_frequency, 296 .vidioc_g_tuner = saa7134_g_tuner, 297 .vidioc_s_tuner = saa7134_s_tuner, 298 .vidioc_enum_input = saa7134_enum_input, 299 .vidioc_g_input = saa7134_g_input, 300 .vidioc_s_input = saa7134_s_input, 301 .vidioc_s_std = saa7134_s_std, 302 .vidioc_g_std = saa7134_g_std, 303}; 304 305/* ----------------------------------------------------------- */ 306 307static struct video_device saa7134_empress_template = { 308 .name = "saa7134-empress", 309 .fops = &ts_fops, 310 .ioctl_ops = &ts_ioctl_ops, 311 312 .tvnorms = SAA7134_NORMS, 313}; 314 315static void empress_signal_update(struct work_struct *work) 316{ 317 struct saa7134_dev* dev = 318 container_of(work, struct saa7134_dev, empress_workqueue); 319 320 if (dev->nosignal) { 321 dprintk("no video signal\n"); 322 } else { 323 dprintk("video signal acquired\n"); 324 } 325} 326 327static void empress_signal_change(struct saa7134_dev *dev) 328{ 329 schedule_work(&dev->empress_workqueue); 330} 331 332static bool empress_ctrl_filter(const struct v4l2_ctrl *ctrl) 333{ 334 switch (ctrl->id) { 335 case V4L2_CID_BRIGHTNESS: 336 case V4L2_CID_HUE: 337 case V4L2_CID_CONTRAST: 338 case V4L2_CID_SATURATION: 339 case V4L2_CID_AUDIO_MUTE: 340 case V4L2_CID_AUDIO_VOLUME: 341 case V4L2_CID_PRIVATE_INVERT: 342 case V4L2_CID_PRIVATE_AUTOMUTE: 343 return true; 344 default: 345 return false; 346 } 347} 348 349static int empress_init(struct saa7134_dev *dev) 350{ 351 struct v4l2_ctrl_handler *hdl = &dev->empress_ctrl_handler; 352 int err; 353 354 dprintk("%s: %s\n",dev->name,__func__); 355 dev->empress_dev = video_device_alloc(); 356 if (NULL == dev->empress_dev) 357 return -ENOMEM; 358 *(dev->empress_dev) = saa7134_empress_template; 359 dev->empress_dev->v4l2_dev = &dev->v4l2_dev; 360 dev->empress_dev->release = video_device_release; 361 snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name), 362 "%s empress (%s)", dev->name, 363 saa7134_boards[dev->board].name); 364 v4l2_ctrl_handler_init(hdl, 21); 365 v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter); 366 if (dev->empress_sd) 367 v4l2_ctrl_add_handler(hdl, dev->empress_sd->ctrl_handler, NULL); 368 if (hdl->error) { 369 video_device_release(dev->empress_dev); 370 return hdl->error; 371 } 372 dev->empress_dev->ctrl_handler = hdl; 373 374 INIT_WORK(&dev->empress_workqueue, empress_signal_update); 375 376 video_set_drvdata(dev->empress_dev, dev); 377 err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, 378 empress_nr[dev->nr]); 379 if (err < 0) { 380 printk(KERN_INFO "%s: can't register video device\n", 381 dev->name); 382 video_device_release(dev->empress_dev); 383 dev->empress_dev = NULL; 384 return err; 385 } 386 printk(KERN_INFO "%s: registered device %s [mpeg]\n", 387 dev->name, video_device_node_name(dev->empress_dev)); 388 389 videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops, 390 &dev->pci->dev, &dev->slock, 391 V4L2_BUF_TYPE_VIDEO_CAPTURE, 392 V4L2_FIELD_ALTERNATE, 393 sizeof(struct saa7134_buf), 394 dev, NULL); 395 396 empress_signal_update(&dev->empress_workqueue); 397 return 0; 398} 399 400static int empress_fini(struct saa7134_dev *dev) 401{ 402 dprintk("%s: %s\n",dev->name,__func__); 403 404 if (NULL == dev->empress_dev) 405 return 0; 406 flush_work(&dev->empress_workqueue); 407 video_unregister_device(dev->empress_dev); 408 v4l2_ctrl_handler_free(&dev->empress_ctrl_handler); 409 dev->empress_dev = NULL; 410 return 0; 411} 412 413static struct saa7134_mpeg_ops empress_ops = { 414 .type = SAA7134_MPEG_EMPRESS, 415 .init = empress_init, 416 .fini = empress_fini, 417 .signal_change = empress_signal_change, 418}; 419 420static int __init empress_register(void) 421{ 422 return saa7134_ts_register(&empress_ops); 423} 424 425static void __exit empress_unregister(void) 426{ 427 saa7134_ts_unregister(&empress_ops); 428} 429 430module_init(empress_register); 431module_exit(empress_unregister); 432 433/* ----------------------------------------------------------- */ 434/* 435 * Local variables: 436 * c-basic-offset: 8 437 * End: 438 */ 439