Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] add blackfin capture bridge driver

This is a v4l2 bridge driver for Blackfin video capture device, support ppi and eppi interface.

Signed-off-by: Scott Jiang <scott.jiang.linux@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Scott Jiang and committed by
Mauro Carvalho Chehab
63b1a90d f877ed97

+1457
+2
drivers/media/video/Kconfig
··· 871 871 872 872 source "drivers/media/video/omap/Kconfig" 873 873 874 + source "drivers/media/video/blackfin/Kconfig" 875 + 874 876 config VIDEO_SH_VOU 875 877 tristate "SuperH VOU video output driver" 876 878 depends on VIDEO_DEV && ARCH_SHMOBILE
+2
drivers/media/video/Makefile
··· 187 187 188 188 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/ 189 189 190 + obj-$(CONFIG_BLACKFIN) += blackfin/ 191 + 190 192 obj-$(CONFIG_ARCH_DAVINCI) += davinci/ 191 193 192 194 obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
+10
drivers/media/video/blackfin/Kconfig
··· 1 + config VIDEO_BLACKFIN_CAPTURE 2 + tristate "Blackfin Video Capture Driver" 3 + depends on VIDEO_V4L2 && BLACKFIN && I2C 4 + select VIDEOBUF2_DMA_CONTIG 5 + help 6 + V4L2 bridge driver for Blackfin video capture device. 7 + Choose PPI or EPPI as its interface. 8 + 9 + To compile this driver as a module, choose M here: the 10 + module will be called bfin_video_capture.
+2
drivers/media/video/blackfin/Makefile
··· 1 + bfin_video_capture-objs := bfin_capture.o ppi.o 2 + obj-$(CONFIG_VIDEO_BLACKFIN_CAPTURE) += bfin_video_capture.o
+1059
drivers/media/video/blackfin/bfin_capture.c
··· 1 + /* 2 + * Analog Devices video capture driver 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 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/completion.h> 21 + #include <linux/delay.h> 22 + #include <linux/errno.h> 23 + #include <linux/fs.h> 24 + #include <linux/i2c.h> 25 + #include <linux/init.h> 26 + #include <linux/interrupt.h> 27 + #include <linux/io.h> 28 + #include <linux/mm.h> 29 + #include <linux/module.h> 30 + #include <linux/platform_device.h> 31 + #include <linux/slab.h> 32 + #include <linux/time.h> 33 + #include <linux/types.h> 34 + 35 + #include <media/v4l2-chip-ident.h> 36 + #include <media/v4l2-common.h> 37 + #include <media/v4l2-ctrls.h> 38 + #include <media/v4l2-device.h> 39 + #include <media/v4l2-ioctl.h> 40 + #include <media/videobuf2-dma-contig.h> 41 + 42 + #include <asm/dma.h> 43 + 44 + #include <media/blackfin/bfin_capture.h> 45 + #include <media/blackfin/ppi.h> 46 + 47 + #define CAPTURE_DRV_NAME "bfin_capture" 48 + #define BCAP_MIN_NUM_BUF 2 49 + 50 + struct bcap_format { 51 + char *desc; 52 + u32 pixelformat; 53 + enum v4l2_mbus_pixelcode mbus_code; 54 + int bpp; /* bits per pixel */ 55 + }; 56 + 57 + struct bcap_buffer { 58 + struct vb2_buffer vb; 59 + struct list_head list; 60 + }; 61 + 62 + struct bcap_device { 63 + /* capture device instance */ 64 + struct v4l2_device v4l2_dev; 65 + /* v4l2 control handler */ 66 + struct v4l2_ctrl_handler ctrl_handler; 67 + /* device node data */ 68 + struct video_device *video_dev; 69 + /* sub device instance */ 70 + struct v4l2_subdev *sd; 71 + /* capture config */ 72 + struct bfin_capture_config *cfg; 73 + /* ppi interface */ 74 + struct ppi_if *ppi; 75 + /* current input */ 76 + unsigned int cur_input; 77 + /* current selected standard */ 78 + v4l2_std_id std; 79 + /* used to store pixel format */ 80 + struct v4l2_pix_format fmt; 81 + /* bits per pixel*/ 82 + int bpp; 83 + /* used to store sensor supported format */ 84 + struct bcap_format *sensor_formats; 85 + /* number of sensor formats array */ 86 + int num_sensor_formats; 87 + /* pointing to current video buffer */ 88 + struct bcap_buffer *cur_frm; 89 + /* pointing to next video buffer */ 90 + struct bcap_buffer *next_frm; 91 + /* buffer queue used in videobuf2 */ 92 + struct vb2_queue buffer_queue; 93 + /* allocator-specific contexts for each plane */ 94 + struct vb2_alloc_ctx *alloc_ctx; 95 + /* queue of filled frames */ 96 + struct list_head dma_queue; 97 + /* used in videobuf2 callback */ 98 + spinlock_t lock; 99 + /* used to access capture device */ 100 + struct mutex mutex; 101 + /* used to wait ppi to complete one transfer */ 102 + struct completion comp; 103 + /* prepare to stop */ 104 + bool stop; 105 + }; 106 + 107 + struct bcap_fh { 108 + struct v4l2_fh fh; 109 + /* indicates whether this file handle is doing IO */ 110 + bool io_allowed; 111 + }; 112 + 113 + static const struct bcap_format bcap_formats[] = { 114 + { 115 + .desc = "YCbCr 4:2:2 Interleaved UYVY", 116 + .pixelformat = V4L2_PIX_FMT_UYVY, 117 + .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, 118 + .bpp = 16, 119 + }, 120 + { 121 + .desc = "YCbCr 4:2:2 Interleaved YUYV", 122 + .pixelformat = V4L2_PIX_FMT_YUYV, 123 + .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, 124 + .bpp = 16, 125 + }, 126 + { 127 + .desc = "RGB 565", 128 + .pixelformat = V4L2_PIX_FMT_RGB565, 129 + .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_LE, 130 + .bpp = 16, 131 + }, 132 + { 133 + .desc = "RGB 444", 134 + .pixelformat = V4L2_PIX_FMT_RGB444, 135 + .mbus_code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, 136 + .bpp = 16, 137 + }, 138 + 139 + }; 140 + #define BCAP_MAX_FMTS ARRAY_SIZE(bcap_formats) 141 + 142 + static irqreturn_t bcap_isr(int irq, void *dev_id); 143 + 144 + static struct bcap_buffer *to_bcap_vb(struct vb2_buffer *vb) 145 + { 146 + return container_of(vb, struct bcap_buffer, vb); 147 + } 148 + 149 + static int bcap_init_sensor_formats(struct bcap_device *bcap_dev) 150 + { 151 + enum v4l2_mbus_pixelcode code; 152 + struct bcap_format *sf; 153 + unsigned int num_formats = 0; 154 + int i, j; 155 + 156 + while (!v4l2_subdev_call(bcap_dev->sd, video, 157 + enum_mbus_fmt, num_formats, &code)) 158 + num_formats++; 159 + if (!num_formats) 160 + return -ENXIO; 161 + 162 + sf = kzalloc(num_formats * sizeof(*sf), GFP_KERNEL); 163 + if (!sf) 164 + return -ENOMEM; 165 + 166 + for (i = 0; i < num_formats; i++) { 167 + v4l2_subdev_call(bcap_dev->sd, video, 168 + enum_mbus_fmt, i, &code); 169 + for (j = 0; j < BCAP_MAX_FMTS; j++) 170 + if (code == bcap_formats[j].mbus_code) 171 + break; 172 + if (j == BCAP_MAX_FMTS) { 173 + /* we don't allow this sensor working with our bridge */ 174 + kfree(sf); 175 + return -EINVAL; 176 + } 177 + sf[i] = bcap_formats[j]; 178 + } 179 + bcap_dev->sensor_formats = sf; 180 + bcap_dev->num_sensor_formats = num_formats; 181 + return 0; 182 + } 183 + 184 + static void bcap_free_sensor_formats(struct bcap_device *bcap_dev) 185 + { 186 + bcap_dev->num_sensor_formats = 0; 187 + kfree(bcap_dev->sensor_formats); 188 + bcap_dev->sensor_formats = NULL; 189 + } 190 + 191 + static int bcap_open(struct file *file) 192 + { 193 + struct bcap_device *bcap_dev = video_drvdata(file); 194 + struct video_device *vfd = bcap_dev->video_dev; 195 + struct bcap_fh *bcap_fh; 196 + 197 + if (!bcap_dev->sd) { 198 + v4l2_err(&bcap_dev->v4l2_dev, "No sub device registered\n"); 199 + return -ENODEV; 200 + } 201 + 202 + bcap_fh = kzalloc(sizeof(*bcap_fh), GFP_KERNEL); 203 + if (!bcap_fh) { 204 + v4l2_err(&bcap_dev->v4l2_dev, 205 + "unable to allocate memory for file handle object\n"); 206 + return -ENOMEM; 207 + } 208 + 209 + v4l2_fh_init(&bcap_fh->fh, vfd); 210 + 211 + /* store pointer to v4l2_fh in private_data member of file */ 212 + file->private_data = &bcap_fh->fh; 213 + v4l2_fh_add(&bcap_fh->fh); 214 + bcap_fh->io_allowed = false; 215 + return 0; 216 + } 217 + 218 + static int bcap_release(struct file *file) 219 + { 220 + struct bcap_device *bcap_dev = video_drvdata(file); 221 + struct v4l2_fh *fh = file->private_data; 222 + struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); 223 + 224 + /* if this instance is doing IO */ 225 + if (bcap_fh->io_allowed) 226 + vb2_queue_release(&bcap_dev->buffer_queue); 227 + 228 + file->private_data = NULL; 229 + v4l2_fh_del(&bcap_fh->fh); 230 + v4l2_fh_exit(&bcap_fh->fh); 231 + kfree(bcap_fh); 232 + return 0; 233 + } 234 + 235 + static int bcap_mmap(struct file *file, struct vm_area_struct *vma) 236 + { 237 + struct bcap_device *bcap_dev = video_drvdata(file); 238 + 239 + return vb2_mmap(&bcap_dev->buffer_queue, vma); 240 + } 241 + 242 + #ifndef CONFIG_MMU 243 + static unsigned long bcap_get_unmapped_area(struct file *file, 244 + unsigned long addr, 245 + unsigned long len, 246 + unsigned long pgoff, 247 + unsigned long flags) 248 + { 249 + struct bcap_device *bcap_dev = video_drvdata(file); 250 + 251 + return vb2_get_unmapped_area(&bcap_dev->buffer_queue, 252 + addr, 253 + len, 254 + pgoff, 255 + flags); 256 + } 257 + #endif 258 + 259 + static unsigned int bcap_poll(struct file *file, poll_table *wait) 260 + { 261 + struct bcap_device *bcap_dev = video_drvdata(file); 262 + 263 + return vb2_poll(&bcap_dev->buffer_queue, file, wait); 264 + } 265 + 266 + static int bcap_queue_setup(struct vb2_queue *vq, 267 + const struct v4l2_format *fmt, 268 + unsigned int *nbuffers, unsigned int *nplanes, 269 + unsigned int sizes[], void *alloc_ctxs[]) 270 + { 271 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 272 + 273 + if (*nbuffers < BCAP_MIN_NUM_BUF) 274 + *nbuffers = BCAP_MIN_NUM_BUF; 275 + 276 + *nplanes = 1; 277 + sizes[0] = bcap_dev->fmt.sizeimage; 278 + alloc_ctxs[0] = bcap_dev->alloc_ctx; 279 + 280 + return 0; 281 + } 282 + 283 + static int bcap_buffer_init(struct vb2_buffer *vb) 284 + { 285 + struct bcap_buffer *buf = to_bcap_vb(vb); 286 + 287 + INIT_LIST_HEAD(&buf->list); 288 + return 0; 289 + } 290 + 291 + static int bcap_buffer_prepare(struct vb2_buffer *vb) 292 + { 293 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); 294 + struct bcap_buffer *buf = to_bcap_vb(vb); 295 + unsigned long size; 296 + 297 + size = bcap_dev->fmt.sizeimage; 298 + if (vb2_plane_size(vb, 0) < size) { 299 + v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n", 300 + vb2_plane_size(vb, 0), size); 301 + return -EINVAL; 302 + } 303 + vb2_set_plane_payload(&buf->vb, 0, size); 304 + 305 + return 0; 306 + } 307 + 308 + static void bcap_buffer_queue(struct vb2_buffer *vb) 309 + { 310 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); 311 + struct bcap_buffer *buf = to_bcap_vb(vb); 312 + unsigned long flags; 313 + 314 + spin_lock_irqsave(&bcap_dev->lock, flags); 315 + list_add_tail(&buf->list, &bcap_dev->dma_queue); 316 + spin_unlock_irqrestore(&bcap_dev->lock, flags); 317 + } 318 + 319 + static void bcap_buffer_cleanup(struct vb2_buffer *vb) 320 + { 321 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); 322 + struct bcap_buffer *buf = to_bcap_vb(vb); 323 + unsigned long flags; 324 + 325 + spin_lock_irqsave(&bcap_dev->lock, flags); 326 + list_del_init(&buf->list); 327 + spin_unlock_irqrestore(&bcap_dev->lock, flags); 328 + } 329 + 330 + static void bcap_lock(struct vb2_queue *vq) 331 + { 332 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 333 + mutex_lock(&bcap_dev->mutex); 334 + } 335 + 336 + static void bcap_unlock(struct vb2_queue *vq) 337 + { 338 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 339 + mutex_unlock(&bcap_dev->mutex); 340 + } 341 + 342 + static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count) 343 + { 344 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 345 + struct ppi_if *ppi = bcap_dev->ppi; 346 + struct ppi_params params; 347 + int ret; 348 + 349 + /* enable streamon on the sub device */ 350 + ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1); 351 + if (ret && (ret != -ENOIOCTLCMD)) { 352 + v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n"); 353 + return ret; 354 + } 355 + 356 + /* set ppi params */ 357 + params.width = bcap_dev->fmt.width; 358 + params.height = bcap_dev->fmt.height; 359 + params.bpp = bcap_dev->bpp; 360 + params.ppi_control = bcap_dev->cfg->ppi_control; 361 + params.int_mask = bcap_dev->cfg->int_mask; 362 + params.blank_clocks = bcap_dev->cfg->blank_clocks; 363 + ret = ppi->ops->set_params(ppi, &params); 364 + if (ret < 0) { 365 + v4l2_err(&bcap_dev->v4l2_dev, 366 + "Error in setting ppi params\n"); 367 + return ret; 368 + } 369 + 370 + /* attach ppi DMA irq handler */ 371 + ret = ppi->ops->attach_irq(ppi, bcap_isr); 372 + if (ret < 0) { 373 + v4l2_err(&bcap_dev->v4l2_dev, 374 + "Error in attaching interrupt handler\n"); 375 + return ret; 376 + } 377 + 378 + INIT_COMPLETION(bcap_dev->comp); 379 + bcap_dev->stop = false; 380 + return 0; 381 + } 382 + 383 + static int bcap_stop_streaming(struct vb2_queue *vq) 384 + { 385 + struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 386 + struct ppi_if *ppi = bcap_dev->ppi; 387 + int ret; 388 + 389 + if (!vb2_is_streaming(vq)) 390 + return 0; 391 + 392 + bcap_dev->stop = true; 393 + wait_for_completion(&bcap_dev->comp); 394 + ppi->ops->stop(ppi); 395 + ppi->ops->detach_irq(ppi); 396 + ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 0); 397 + if (ret && (ret != -ENOIOCTLCMD)) 398 + v4l2_err(&bcap_dev->v4l2_dev, 399 + "stream off failed in subdev\n"); 400 + 401 + /* release all active buffers */ 402 + while (!list_empty(&bcap_dev->dma_queue)) { 403 + bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, 404 + struct bcap_buffer, list); 405 + list_del(&bcap_dev->next_frm->list); 406 + vb2_buffer_done(&bcap_dev->next_frm->vb, VB2_BUF_STATE_ERROR); 407 + } 408 + return 0; 409 + } 410 + 411 + static struct vb2_ops bcap_video_qops = { 412 + .queue_setup = bcap_queue_setup, 413 + .buf_init = bcap_buffer_init, 414 + .buf_prepare = bcap_buffer_prepare, 415 + .buf_cleanup = bcap_buffer_cleanup, 416 + .buf_queue = bcap_buffer_queue, 417 + .wait_prepare = bcap_unlock, 418 + .wait_finish = bcap_lock, 419 + .start_streaming = bcap_start_streaming, 420 + .stop_streaming = bcap_stop_streaming, 421 + }; 422 + 423 + static int bcap_reqbufs(struct file *file, void *priv, 424 + struct v4l2_requestbuffers *req_buf) 425 + { 426 + struct bcap_device *bcap_dev = video_drvdata(file); 427 + struct vb2_queue *vq = &bcap_dev->buffer_queue; 428 + struct v4l2_fh *fh = file->private_data; 429 + struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); 430 + 431 + if (vb2_is_busy(vq)) 432 + return -EBUSY; 433 + 434 + bcap_fh->io_allowed = true; 435 + 436 + return vb2_reqbufs(vq, req_buf); 437 + } 438 + 439 + static int bcap_querybuf(struct file *file, void *priv, 440 + struct v4l2_buffer *buf) 441 + { 442 + struct bcap_device *bcap_dev = video_drvdata(file); 443 + 444 + return vb2_querybuf(&bcap_dev->buffer_queue, buf); 445 + } 446 + 447 + static int bcap_qbuf(struct file *file, void *priv, 448 + struct v4l2_buffer *buf) 449 + { 450 + struct bcap_device *bcap_dev = video_drvdata(file); 451 + struct v4l2_fh *fh = file->private_data; 452 + struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); 453 + 454 + if (!bcap_fh->io_allowed) 455 + return -EBUSY; 456 + 457 + return vb2_qbuf(&bcap_dev->buffer_queue, buf); 458 + } 459 + 460 + static int bcap_dqbuf(struct file *file, void *priv, 461 + struct v4l2_buffer *buf) 462 + { 463 + struct bcap_device *bcap_dev = video_drvdata(file); 464 + struct v4l2_fh *fh = file->private_data; 465 + struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh); 466 + 467 + if (!bcap_fh->io_allowed) 468 + return -EBUSY; 469 + 470 + return vb2_dqbuf(&bcap_dev->buffer_queue, 471 + buf, file->f_flags & O_NONBLOCK); 472 + } 473 + 474 + static irqreturn_t bcap_isr(int irq, void *dev_id) 475 + { 476 + struct ppi_if *ppi = dev_id; 477 + struct bcap_device *bcap_dev = ppi->priv; 478 + struct timeval timevalue; 479 + struct vb2_buffer *vb = &bcap_dev->cur_frm->vb; 480 + dma_addr_t addr; 481 + 482 + spin_lock(&bcap_dev->lock); 483 + 484 + if (bcap_dev->cur_frm != bcap_dev->next_frm) { 485 + do_gettimeofday(&timevalue); 486 + vb->v4l2_buf.timestamp = timevalue; 487 + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); 488 + bcap_dev->cur_frm = bcap_dev->next_frm; 489 + } 490 + 491 + ppi->ops->stop(ppi); 492 + 493 + if (bcap_dev->stop) { 494 + complete(&bcap_dev->comp); 495 + } else { 496 + if (!list_empty(&bcap_dev->dma_queue)) { 497 + bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, 498 + struct bcap_buffer, list); 499 + list_del(&bcap_dev->next_frm->list); 500 + addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->next_frm->vb, 0); 501 + ppi->ops->update_addr(ppi, (unsigned long)addr); 502 + } 503 + ppi->ops->start(ppi); 504 + } 505 + 506 + spin_unlock(&bcap_dev->lock); 507 + 508 + return IRQ_HANDLED; 509 + } 510 + 511 + static int bcap_streamon(struct file *file, void *priv, 512 + enum v4l2_buf_type buf_type) 513 + { 514 + struct bcap_device *bcap_dev = video_drvdata(file); 515 + struct bcap_fh *fh = file->private_data; 516 + struct ppi_if *ppi = bcap_dev->ppi; 517 + dma_addr_t addr; 518 + int ret; 519 + 520 + if (!fh->io_allowed) 521 + return -EBUSY; 522 + 523 + /* call streamon to start streaming in videobuf */ 524 + ret = vb2_streamon(&bcap_dev->buffer_queue, buf_type); 525 + if (ret) 526 + return ret; 527 + 528 + /* if dma queue is empty, return error */ 529 + if (list_empty(&bcap_dev->dma_queue)) { 530 + v4l2_err(&bcap_dev->v4l2_dev, "dma queue is empty\n"); 531 + ret = -EINVAL; 532 + goto err; 533 + } 534 + 535 + /* get the next frame from the dma queue */ 536 + bcap_dev->next_frm = list_entry(bcap_dev->dma_queue.next, 537 + struct bcap_buffer, list); 538 + bcap_dev->cur_frm = bcap_dev->next_frm; 539 + /* remove buffer from the dma queue */ 540 + list_del(&bcap_dev->cur_frm->list); 541 + addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0); 542 + /* update DMA address */ 543 + ppi->ops->update_addr(ppi, (unsigned long)addr); 544 + /* enable ppi */ 545 + ppi->ops->start(ppi); 546 + 547 + return 0; 548 + err: 549 + vb2_streamoff(&bcap_dev->buffer_queue, buf_type); 550 + return ret; 551 + } 552 + 553 + static int bcap_streamoff(struct file *file, void *priv, 554 + enum v4l2_buf_type buf_type) 555 + { 556 + struct bcap_device *bcap_dev = video_drvdata(file); 557 + struct bcap_fh *fh = file->private_data; 558 + 559 + if (!fh->io_allowed) 560 + return -EBUSY; 561 + 562 + return vb2_streamoff(&bcap_dev->buffer_queue, buf_type); 563 + } 564 + 565 + static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std) 566 + { 567 + struct bcap_device *bcap_dev = video_drvdata(file); 568 + 569 + return v4l2_subdev_call(bcap_dev->sd, video, querystd, std); 570 + } 571 + 572 + static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std) 573 + { 574 + struct bcap_device *bcap_dev = video_drvdata(file); 575 + 576 + *std = bcap_dev->std; 577 + return 0; 578 + } 579 + 580 + static int bcap_s_std(struct file *file, void *priv, v4l2_std_id *std) 581 + { 582 + struct bcap_device *bcap_dev = video_drvdata(file); 583 + int ret; 584 + 585 + if (vb2_is_busy(&bcap_dev->buffer_queue)) 586 + return -EBUSY; 587 + 588 + ret = v4l2_subdev_call(bcap_dev->sd, core, s_std, *std); 589 + if (ret < 0) 590 + return ret; 591 + 592 + bcap_dev->std = *std; 593 + return 0; 594 + } 595 + 596 + static int bcap_enum_input(struct file *file, void *priv, 597 + struct v4l2_input *input) 598 + { 599 + struct bcap_device *bcap_dev = video_drvdata(file); 600 + struct bfin_capture_config *config = bcap_dev->cfg; 601 + int ret; 602 + u32 status; 603 + 604 + if (input->index >= config->num_inputs) 605 + return -EINVAL; 606 + 607 + *input = config->inputs[input->index]; 608 + /* get input status */ 609 + ret = v4l2_subdev_call(bcap_dev->sd, video, g_input_status, &status); 610 + if (!ret) 611 + input->status = status; 612 + return 0; 613 + } 614 + 615 + static int bcap_g_input(struct file *file, void *priv, unsigned int *index) 616 + { 617 + struct bcap_device *bcap_dev = video_drvdata(file); 618 + 619 + *index = bcap_dev->cur_input; 620 + return 0; 621 + } 622 + 623 + static int bcap_s_input(struct file *file, void *priv, unsigned int index) 624 + { 625 + struct bcap_device *bcap_dev = video_drvdata(file); 626 + struct bfin_capture_config *config = bcap_dev->cfg; 627 + struct bcap_route *route; 628 + int ret; 629 + 630 + if (vb2_is_busy(&bcap_dev->buffer_queue)) 631 + return -EBUSY; 632 + 633 + if (index >= config->num_inputs) 634 + return -EINVAL; 635 + 636 + route = &config->routes[index]; 637 + ret = v4l2_subdev_call(bcap_dev->sd, video, s_routing, 638 + route->input, route->output, 0); 639 + if ((ret < 0) && (ret != -ENOIOCTLCMD)) { 640 + v4l2_err(&bcap_dev->v4l2_dev, "Failed to set input\n"); 641 + return ret; 642 + } 643 + bcap_dev->cur_input = index; 644 + return 0; 645 + } 646 + 647 + static int bcap_try_format(struct bcap_device *bcap, 648 + struct v4l2_pix_format *pixfmt, 649 + enum v4l2_mbus_pixelcode *mbus_code, 650 + int *bpp) 651 + { 652 + struct bcap_format *sf = bcap->sensor_formats; 653 + struct bcap_format *fmt = NULL; 654 + struct v4l2_mbus_framefmt mbus_fmt; 655 + int ret, i; 656 + 657 + for (i = 0; i < bcap->num_sensor_formats; i++) { 658 + fmt = &sf[i]; 659 + if (pixfmt->pixelformat == fmt->pixelformat) 660 + break; 661 + } 662 + if (i == bcap->num_sensor_formats) 663 + fmt = &sf[0]; 664 + 665 + if (mbus_code) 666 + *mbus_code = fmt->mbus_code; 667 + if (bpp) 668 + *bpp = fmt->bpp; 669 + v4l2_fill_mbus_format(&mbus_fmt, pixfmt, fmt->mbus_code); 670 + ret = v4l2_subdev_call(bcap->sd, video, 671 + try_mbus_fmt, &mbus_fmt); 672 + if (ret < 0) 673 + return ret; 674 + v4l2_fill_pix_format(pixfmt, &mbus_fmt); 675 + pixfmt->bytesperline = pixfmt->width * fmt->bpp / 8; 676 + pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; 677 + return 0; 678 + } 679 + 680 + static int bcap_enum_fmt_vid_cap(struct file *file, void *priv, 681 + struct v4l2_fmtdesc *fmt) 682 + { 683 + struct bcap_device *bcap_dev = video_drvdata(file); 684 + struct bcap_format *sf = bcap_dev->sensor_formats; 685 + 686 + if (fmt->index >= bcap_dev->num_sensor_formats) 687 + return -EINVAL; 688 + 689 + fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 690 + strlcpy(fmt->description, 691 + sf[fmt->index].desc, 692 + sizeof(fmt->description)); 693 + fmt->pixelformat = sf[fmt->index].pixelformat; 694 + return 0; 695 + } 696 + 697 + static int bcap_try_fmt_vid_cap(struct file *file, void *priv, 698 + struct v4l2_format *fmt) 699 + { 700 + struct bcap_device *bcap_dev = video_drvdata(file); 701 + struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 702 + 703 + return bcap_try_format(bcap_dev, pixfmt, NULL, NULL); 704 + } 705 + 706 + static int bcap_g_fmt_vid_cap(struct file *file, void *priv, 707 + struct v4l2_format *fmt) 708 + { 709 + struct bcap_device *bcap_dev = video_drvdata(file); 710 + 711 + fmt->fmt.pix = bcap_dev->fmt; 712 + return 0; 713 + } 714 + 715 + static int bcap_s_fmt_vid_cap(struct file *file, void *priv, 716 + struct v4l2_format *fmt) 717 + { 718 + struct bcap_device *bcap_dev = video_drvdata(file); 719 + struct v4l2_mbus_framefmt mbus_fmt; 720 + enum v4l2_mbus_pixelcode mbus_code; 721 + struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 722 + int ret, bpp; 723 + 724 + if (vb2_is_busy(&bcap_dev->buffer_queue)) 725 + return -EBUSY; 726 + 727 + /* see if format works */ 728 + ret = bcap_try_format(bcap_dev, pixfmt, &mbus_code, &bpp); 729 + if (ret < 0) 730 + return ret; 731 + 732 + v4l2_fill_mbus_format(&mbus_fmt, pixfmt, mbus_code); 733 + ret = v4l2_subdev_call(bcap_dev->sd, video, s_mbus_fmt, &mbus_fmt); 734 + if (ret < 0) 735 + return ret; 736 + bcap_dev->fmt = *pixfmt; 737 + bcap_dev->bpp = bpp; 738 + return 0; 739 + } 740 + 741 + static int bcap_querycap(struct file *file, void *priv, 742 + struct v4l2_capability *cap) 743 + { 744 + struct bcap_device *bcap_dev = video_drvdata(file); 745 + 746 + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 747 + strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver)); 748 + strlcpy(cap->bus_info, "Blackfin Platform", sizeof(cap->bus_info)); 749 + strlcpy(cap->card, bcap_dev->cfg->card_name, sizeof(cap->card)); 750 + return 0; 751 + } 752 + 753 + static int bcap_g_parm(struct file *file, void *fh, 754 + struct v4l2_streamparm *a) 755 + { 756 + struct bcap_device *bcap_dev = video_drvdata(file); 757 + 758 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 759 + return -EINVAL; 760 + return v4l2_subdev_call(bcap_dev->sd, video, g_parm, a); 761 + } 762 + 763 + static int bcap_s_parm(struct file *file, void *fh, 764 + struct v4l2_streamparm *a) 765 + { 766 + struct bcap_device *bcap_dev = video_drvdata(file); 767 + 768 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 769 + return -EINVAL; 770 + return v4l2_subdev_call(bcap_dev->sd, video, s_parm, a); 771 + } 772 + 773 + static int bcap_g_chip_ident(struct file *file, void *priv, 774 + struct v4l2_dbg_chip_ident *chip) 775 + { 776 + struct bcap_device *bcap_dev = video_drvdata(file); 777 + 778 + chip->ident = V4L2_IDENT_NONE; 779 + chip->revision = 0; 780 + if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER && 781 + chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 782 + return -EINVAL; 783 + 784 + return v4l2_subdev_call(bcap_dev->sd, core, 785 + g_chip_ident, chip); 786 + } 787 + 788 + #ifdef CONFIG_VIDEO_ADV_DEBUG 789 + static int bcap_dbg_g_register(struct file *file, void *priv, 790 + struct v4l2_dbg_register *reg) 791 + { 792 + struct bcap_device *bcap_dev = video_drvdata(file); 793 + 794 + return v4l2_subdev_call(bcap_dev->sd, core, 795 + g_register, reg); 796 + } 797 + 798 + static int bcap_dbg_s_register(struct file *file, void *priv, 799 + struct v4l2_dbg_register *reg) 800 + { 801 + struct bcap_device *bcap_dev = video_drvdata(file); 802 + 803 + return v4l2_subdev_call(bcap_dev->sd, core, 804 + s_register, reg); 805 + } 806 + #endif 807 + 808 + static int bcap_log_status(struct file *file, void *priv) 809 + { 810 + struct bcap_device *bcap_dev = video_drvdata(file); 811 + /* status for sub devices */ 812 + v4l2_device_call_all(&bcap_dev->v4l2_dev, 0, core, log_status); 813 + return 0; 814 + } 815 + 816 + static const struct v4l2_ioctl_ops bcap_ioctl_ops = { 817 + .vidioc_querycap = bcap_querycap, 818 + .vidioc_g_fmt_vid_cap = bcap_g_fmt_vid_cap, 819 + .vidioc_enum_fmt_vid_cap = bcap_enum_fmt_vid_cap, 820 + .vidioc_s_fmt_vid_cap = bcap_s_fmt_vid_cap, 821 + .vidioc_try_fmt_vid_cap = bcap_try_fmt_vid_cap, 822 + .vidioc_enum_input = bcap_enum_input, 823 + .vidioc_g_input = bcap_g_input, 824 + .vidioc_s_input = bcap_s_input, 825 + .vidioc_querystd = bcap_querystd, 826 + .vidioc_s_std = bcap_s_std, 827 + .vidioc_g_std = bcap_g_std, 828 + .vidioc_reqbufs = bcap_reqbufs, 829 + .vidioc_querybuf = bcap_querybuf, 830 + .vidioc_qbuf = bcap_qbuf, 831 + .vidioc_dqbuf = bcap_dqbuf, 832 + .vidioc_streamon = bcap_streamon, 833 + .vidioc_streamoff = bcap_streamoff, 834 + .vidioc_g_parm = bcap_g_parm, 835 + .vidioc_s_parm = bcap_s_parm, 836 + .vidioc_g_chip_ident = bcap_g_chip_ident, 837 + #ifdef CONFIG_VIDEO_ADV_DEBUG 838 + .vidioc_g_register = bcap_dbg_g_register, 839 + .vidioc_s_register = bcap_dbg_s_register, 840 + #endif 841 + .vidioc_log_status = bcap_log_status, 842 + }; 843 + 844 + static struct v4l2_file_operations bcap_fops = { 845 + .owner = THIS_MODULE, 846 + .open = bcap_open, 847 + .release = bcap_release, 848 + .unlocked_ioctl = video_ioctl2, 849 + .mmap = bcap_mmap, 850 + #ifndef CONFIG_MMU 851 + .get_unmapped_area = bcap_get_unmapped_area, 852 + #endif 853 + .poll = bcap_poll 854 + }; 855 + 856 + static int __devinit bcap_probe(struct platform_device *pdev) 857 + { 858 + struct bcap_device *bcap_dev; 859 + struct video_device *vfd; 860 + struct i2c_adapter *i2c_adap; 861 + struct bfin_capture_config *config; 862 + struct vb2_queue *q; 863 + int ret; 864 + 865 + config = pdev->dev.platform_data; 866 + if (!config) { 867 + v4l2_err(pdev->dev.driver, "Unable to get board config\n"); 868 + return -ENODEV; 869 + } 870 + 871 + bcap_dev = kzalloc(sizeof(*bcap_dev), GFP_KERNEL); 872 + if (!bcap_dev) { 873 + v4l2_err(pdev->dev.driver, "Unable to alloc bcap_dev\n"); 874 + return -ENOMEM; 875 + } 876 + 877 + bcap_dev->cfg = config; 878 + 879 + bcap_dev->ppi = ppi_create_instance(config->ppi_info); 880 + if (!bcap_dev->ppi) { 881 + v4l2_err(pdev->dev.driver, "Unable to create ppi\n"); 882 + ret = -ENODEV; 883 + goto err_free_dev; 884 + } 885 + bcap_dev->ppi->priv = bcap_dev; 886 + 887 + bcap_dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 888 + if (IS_ERR(bcap_dev->alloc_ctx)) { 889 + ret = PTR_ERR(bcap_dev->alloc_ctx); 890 + goto err_free_ppi; 891 + } 892 + 893 + vfd = video_device_alloc(); 894 + if (!vfd) { 895 + ret = -ENOMEM; 896 + v4l2_err(pdev->dev.driver, "Unable to alloc video device\n"); 897 + goto err_cleanup_ctx; 898 + } 899 + 900 + /* initialize field of video device */ 901 + vfd->release = video_device_release; 902 + vfd->fops = &bcap_fops; 903 + vfd->ioctl_ops = &bcap_ioctl_ops; 904 + vfd->tvnorms = 0; 905 + vfd->v4l2_dev = &bcap_dev->v4l2_dev; 906 + set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); 907 + strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name)); 908 + bcap_dev->video_dev = vfd; 909 + 910 + ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev); 911 + if (ret) { 912 + v4l2_err(pdev->dev.driver, 913 + "Unable to register v4l2 device\n"); 914 + goto err_release_vdev; 915 + } 916 + v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n"); 917 + 918 + bcap_dev->v4l2_dev.ctrl_handler = &bcap_dev->ctrl_handler; 919 + ret = v4l2_ctrl_handler_init(&bcap_dev->ctrl_handler, 0); 920 + if (ret) { 921 + v4l2_err(&bcap_dev->v4l2_dev, 922 + "Unable to init control handler\n"); 923 + goto err_unreg_v4l2; 924 + } 925 + 926 + spin_lock_init(&bcap_dev->lock); 927 + /* initialize queue */ 928 + q = &bcap_dev->buffer_queue; 929 + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 930 + q->io_modes = VB2_MMAP; 931 + q->drv_priv = bcap_dev; 932 + q->buf_struct_size = sizeof(struct bcap_buffer); 933 + q->ops = &bcap_video_qops; 934 + q->mem_ops = &vb2_dma_contig_memops; 935 + 936 + vb2_queue_init(q); 937 + 938 + mutex_init(&bcap_dev->mutex); 939 + init_completion(&bcap_dev->comp); 940 + 941 + /* init video dma queues */ 942 + INIT_LIST_HEAD(&bcap_dev->dma_queue); 943 + 944 + vfd->lock = &bcap_dev->mutex; 945 + 946 + /* register video device */ 947 + ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1); 948 + if (ret) { 949 + v4l2_err(&bcap_dev->v4l2_dev, 950 + "Unable to register video device\n"); 951 + goto err_free_handler; 952 + } 953 + video_set_drvdata(bcap_dev->video_dev, bcap_dev); 954 + v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n", 955 + video_device_node_name(vfd)); 956 + 957 + /* load up the subdevice */ 958 + i2c_adap = i2c_get_adapter(config->i2c_adapter_id); 959 + if (!i2c_adap) { 960 + v4l2_err(&bcap_dev->v4l2_dev, 961 + "Unable to find i2c adapter\n"); 962 + goto err_unreg_vdev; 963 + 964 + } 965 + bcap_dev->sd = v4l2_i2c_new_subdev_board(&bcap_dev->v4l2_dev, 966 + i2c_adap, 967 + &config->board_info, 968 + NULL); 969 + if (bcap_dev->sd) { 970 + int i; 971 + /* update tvnorms from the sub devices */ 972 + for (i = 0; i < config->num_inputs; i++) 973 + vfd->tvnorms |= config->inputs[i].std; 974 + } else { 975 + v4l2_err(&bcap_dev->v4l2_dev, 976 + "Unable to register sub device\n"); 977 + goto err_unreg_vdev; 978 + } 979 + 980 + v4l2_info(&bcap_dev->v4l2_dev, "v4l2 sub device registered\n"); 981 + 982 + /* now we can probe the default state */ 983 + if (vfd->tvnorms) { 984 + v4l2_std_id std; 985 + ret = v4l2_subdev_call(bcap_dev->sd, core, g_std, &std); 986 + if (ret) { 987 + v4l2_err(&bcap_dev->v4l2_dev, 988 + "Unable to get std\n"); 989 + goto err_unreg_vdev; 990 + } 991 + bcap_dev->std = std; 992 + } 993 + ret = bcap_init_sensor_formats(bcap_dev); 994 + if (ret) { 995 + v4l2_err(&bcap_dev->v4l2_dev, 996 + "Unable to create sensor formats table\n"); 997 + goto err_unreg_vdev; 998 + } 999 + return 0; 1000 + err_unreg_vdev: 1001 + video_unregister_device(bcap_dev->video_dev); 1002 + bcap_dev->video_dev = NULL; 1003 + err_free_handler: 1004 + v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); 1005 + err_unreg_v4l2: 1006 + v4l2_device_unregister(&bcap_dev->v4l2_dev); 1007 + err_release_vdev: 1008 + if (bcap_dev->video_dev) 1009 + video_device_release(bcap_dev->video_dev); 1010 + err_cleanup_ctx: 1011 + vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); 1012 + err_free_ppi: 1013 + ppi_delete_instance(bcap_dev->ppi); 1014 + err_free_dev: 1015 + kfree(bcap_dev); 1016 + return ret; 1017 + } 1018 + 1019 + static int __devexit bcap_remove(struct platform_device *pdev) 1020 + { 1021 + struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev); 1022 + struct bcap_device *bcap_dev = container_of(v4l2_dev, 1023 + struct bcap_device, v4l2_dev); 1024 + 1025 + bcap_free_sensor_formats(bcap_dev); 1026 + video_unregister_device(bcap_dev->video_dev); 1027 + v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); 1028 + v4l2_device_unregister(v4l2_dev); 1029 + vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); 1030 + ppi_delete_instance(bcap_dev->ppi); 1031 + kfree(bcap_dev); 1032 + return 0; 1033 + } 1034 + 1035 + static struct platform_driver bcap_driver = { 1036 + .driver = { 1037 + .name = CAPTURE_DRV_NAME, 1038 + .owner = THIS_MODULE, 1039 + }, 1040 + .probe = bcap_probe, 1041 + .remove = __devexit_p(bcap_remove), 1042 + }; 1043 + 1044 + static __init int bcap_init(void) 1045 + { 1046 + return platform_driver_register(&bcap_driver); 1047 + } 1048 + 1049 + static __exit void bcap_exit(void) 1050 + { 1051 + platform_driver_unregister(&bcap_driver); 1052 + } 1053 + 1054 + module_init(bcap_init); 1055 + module_exit(bcap_exit); 1056 + 1057 + MODULE_DESCRIPTION("Analog Devices blackfin video capture driver"); 1058 + MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>"); 1059 + MODULE_LICENSE("GPL v2");
+271
drivers/media/video/blackfin/ppi.c
··· 1 + /* 2 + * ppi.c Analog Devices Parallel Peripheral Interface driver 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 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/slab.h> 21 + 22 + #include <asm/bfin_ppi.h> 23 + #include <asm/blackfin.h> 24 + #include <asm/cacheflush.h> 25 + #include <asm/dma.h> 26 + #include <asm/portmux.h> 27 + 28 + #include <media/blackfin/ppi.h> 29 + 30 + static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler); 31 + static void ppi_detach_irq(struct ppi_if *ppi); 32 + static int ppi_start(struct ppi_if *ppi); 33 + static int ppi_stop(struct ppi_if *ppi); 34 + static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params); 35 + static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr); 36 + 37 + static const struct ppi_ops ppi_ops = { 38 + .attach_irq = ppi_attach_irq, 39 + .detach_irq = ppi_detach_irq, 40 + .start = ppi_start, 41 + .stop = ppi_stop, 42 + .set_params = ppi_set_params, 43 + .update_addr = ppi_update_addr, 44 + }; 45 + 46 + static irqreturn_t ppi_irq_err(int irq, void *dev_id) 47 + { 48 + struct ppi_if *ppi = dev_id; 49 + const struct ppi_info *info = ppi->info; 50 + 51 + switch (info->type) { 52 + case PPI_TYPE_PPI: 53 + { 54 + struct bfin_ppi_regs *reg = info->base; 55 + unsigned short status; 56 + 57 + /* register on bf561 is cleared when read 58 + * others are W1C 59 + */ 60 + status = bfin_read16(&reg->status); 61 + bfin_write16(&reg->status, 0xff00); 62 + break; 63 + } 64 + case PPI_TYPE_EPPI: 65 + { 66 + struct bfin_eppi_regs *reg = info->base; 67 + bfin_write16(&reg->status, 0xffff); 68 + break; 69 + } 70 + default: 71 + break; 72 + } 73 + 74 + return IRQ_HANDLED; 75 + } 76 + 77 + static int ppi_attach_irq(struct ppi_if *ppi, irq_handler_t handler) 78 + { 79 + const struct ppi_info *info = ppi->info; 80 + int ret; 81 + 82 + ret = request_dma(info->dma_ch, "PPI_DMA"); 83 + 84 + if (ret) { 85 + pr_err("Unable to allocate DMA channel for PPI\n"); 86 + return ret; 87 + } 88 + set_dma_callback(info->dma_ch, handler, ppi); 89 + 90 + if (ppi->err_int) { 91 + ret = request_irq(info->irq_err, ppi_irq_err, 0, "PPI ERROR", ppi); 92 + if (ret) { 93 + pr_err("Unable to allocate IRQ for PPI\n"); 94 + free_dma(info->dma_ch); 95 + } 96 + } 97 + return ret; 98 + } 99 + 100 + static void ppi_detach_irq(struct ppi_if *ppi) 101 + { 102 + const struct ppi_info *info = ppi->info; 103 + 104 + if (ppi->err_int) 105 + free_irq(info->irq_err, ppi); 106 + free_dma(info->dma_ch); 107 + } 108 + 109 + static int ppi_start(struct ppi_if *ppi) 110 + { 111 + const struct ppi_info *info = ppi->info; 112 + 113 + /* enable DMA */ 114 + enable_dma(info->dma_ch); 115 + 116 + /* enable PPI */ 117 + ppi->ppi_control |= PORT_EN; 118 + switch (info->type) { 119 + case PPI_TYPE_PPI: 120 + { 121 + struct bfin_ppi_regs *reg = info->base; 122 + bfin_write16(&reg->control, ppi->ppi_control); 123 + break; 124 + } 125 + case PPI_TYPE_EPPI: 126 + { 127 + struct bfin_eppi_regs *reg = info->base; 128 + bfin_write32(&reg->control, ppi->ppi_control); 129 + break; 130 + } 131 + default: 132 + return -EINVAL; 133 + } 134 + 135 + SSYNC(); 136 + return 0; 137 + } 138 + 139 + static int ppi_stop(struct ppi_if *ppi) 140 + { 141 + const struct ppi_info *info = ppi->info; 142 + 143 + /* disable PPI */ 144 + ppi->ppi_control &= ~PORT_EN; 145 + switch (info->type) { 146 + case PPI_TYPE_PPI: 147 + { 148 + struct bfin_ppi_regs *reg = info->base; 149 + bfin_write16(&reg->control, ppi->ppi_control); 150 + break; 151 + } 152 + case PPI_TYPE_EPPI: 153 + { 154 + struct bfin_eppi_regs *reg = info->base; 155 + bfin_write32(&reg->control, ppi->ppi_control); 156 + break; 157 + } 158 + default: 159 + return -EINVAL; 160 + } 161 + 162 + /* disable DMA */ 163 + clear_dma_irqstat(info->dma_ch); 164 + disable_dma(info->dma_ch); 165 + 166 + SSYNC(); 167 + return 0; 168 + } 169 + 170 + static int ppi_set_params(struct ppi_if *ppi, struct ppi_params *params) 171 + { 172 + const struct ppi_info *info = ppi->info; 173 + int dma32 = 0; 174 + int dma_config, bytes_per_line, lines_per_frame; 175 + 176 + bytes_per_line = params->width * params->bpp / 8; 177 + lines_per_frame = params->height; 178 + if (params->int_mask == 0xFFFFFFFF) 179 + ppi->err_int = false; 180 + else 181 + ppi->err_int = true; 182 + 183 + dma_config = (DMA_FLOW_STOP | WNR | RESTART | DMA2D | DI_EN); 184 + ppi->ppi_control = params->ppi_control & ~PORT_EN; 185 + switch (info->type) { 186 + case PPI_TYPE_PPI: 187 + { 188 + struct bfin_ppi_regs *reg = info->base; 189 + 190 + if (params->ppi_control & DMA32) 191 + dma32 = 1; 192 + 193 + bfin_write16(&reg->control, ppi->ppi_control); 194 + bfin_write16(&reg->count, bytes_per_line - 1); 195 + bfin_write16(&reg->frame, lines_per_frame); 196 + break; 197 + } 198 + case PPI_TYPE_EPPI: 199 + { 200 + struct bfin_eppi_regs *reg = info->base; 201 + 202 + if ((params->ppi_control & PACK_EN) 203 + || (params->ppi_control & 0x38000) > DLEN_16) 204 + dma32 = 1; 205 + 206 + bfin_write32(&reg->control, ppi->ppi_control); 207 + bfin_write16(&reg->line, bytes_per_line + params->blank_clocks); 208 + bfin_write16(&reg->frame, lines_per_frame); 209 + bfin_write16(&reg->hdelay, 0); 210 + bfin_write16(&reg->vdelay, 0); 211 + bfin_write16(&reg->hcount, bytes_per_line); 212 + bfin_write16(&reg->vcount, lines_per_frame); 213 + break; 214 + } 215 + default: 216 + return -EINVAL; 217 + } 218 + 219 + if (dma32) { 220 + dma_config |= WDSIZE_32; 221 + set_dma_x_count(info->dma_ch, bytes_per_line >> 2); 222 + set_dma_x_modify(info->dma_ch, 4); 223 + set_dma_y_modify(info->dma_ch, 4); 224 + } else { 225 + dma_config |= WDSIZE_16; 226 + set_dma_x_count(info->dma_ch, bytes_per_line >> 1); 227 + set_dma_x_modify(info->dma_ch, 2); 228 + set_dma_y_modify(info->dma_ch, 2); 229 + } 230 + set_dma_y_count(info->dma_ch, lines_per_frame); 231 + set_dma_config(info->dma_ch, dma_config); 232 + 233 + SSYNC(); 234 + return 0; 235 + } 236 + 237 + static void ppi_update_addr(struct ppi_if *ppi, unsigned long addr) 238 + { 239 + set_dma_start_addr(ppi->info->dma_ch, addr); 240 + } 241 + 242 + struct ppi_if *ppi_create_instance(const struct ppi_info *info) 243 + { 244 + struct ppi_if *ppi; 245 + 246 + if (!info || !info->pin_req) 247 + return NULL; 248 + 249 + if (peripheral_request_list(info->pin_req, KBUILD_MODNAME)) { 250 + pr_err("request peripheral failed\n"); 251 + return NULL; 252 + } 253 + 254 + ppi = kzalloc(sizeof(*ppi), GFP_KERNEL); 255 + if (!ppi) { 256 + peripheral_free_list(info->pin_req); 257 + pr_err("unable to allocate memory for ppi handle\n"); 258 + return NULL; 259 + } 260 + ppi->ops = &ppi_ops; 261 + ppi->info = info; 262 + 263 + pr_info("ppi probe success\n"); 264 + return ppi; 265 + } 266 + 267 + void ppi_delete_instance(struct ppi_if *ppi) 268 + { 269 + peripheral_free_list(ppi->info->pin_req); 270 + kfree(ppi); 271 + }
+37
include/media/blackfin/bfin_capture.h
··· 1 + #ifndef _BFIN_CAPTURE_H_ 2 + #define _BFIN_CAPTURE_H_ 3 + 4 + #include <linux/i2c.h> 5 + 6 + struct v4l2_input; 7 + struct ppi_info; 8 + 9 + struct bcap_route { 10 + u32 input; 11 + u32 output; 12 + }; 13 + 14 + struct bfin_capture_config { 15 + /* card name */ 16 + char *card_name; 17 + /* inputs available at the sub device */ 18 + struct v4l2_input *inputs; 19 + /* number of inputs supported */ 20 + int num_inputs; 21 + /* routing information for each input */ 22 + struct bcap_route *routes; 23 + /* i2c bus adapter no */ 24 + int i2c_adapter_id; 25 + /* i2c subdevice board info */ 26 + struct i2c_board_info board_info; 27 + /* ppi board info */ 28 + const struct ppi_info *ppi_info; 29 + /* ppi control */ 30 + unsigned long ppi_control; 31 + /* ppi interrupt mask */ 32 + u32 int_mask; 33 + /* horizontal blanking clocks */ 34 + int blank_clocks; 35 + }; 36 + 37 + #endif
+74
include/media/blackfin/ppi.h
··· 1 + /* 2 + * Analog Devices PPI header file 3 + * 4 + * Copyright (c) 2011 Analog Devices Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 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 + #ifndef _PPI_H_ 21 + #define _PPI_H_ 22 + 23 + #include <linux/interrupt.h> 24 + 25 + #ifdef EPPI_EN 26 + #define PORT_EN EPPI_EN 27 + #define DMA32 0 28 + #define PACK_EN PACKEN 29 + #endif 30 + 31 + struct ppi_if; 32 + 33 + struct ppi_params { 34 + int width; 35 + int height; 36 + int bpp; 37 + unsigned long ppi_control; 38 + u32 int_mask; 39 + int blank_clocks; 40 + }; 41 + 42 + struct ppi_ops { 43 + int (*attach_irq)(struct ppi_if *ppi, irq_handler_t handler); 44 + void (*detach_irq)(struct ppi_if *ppi); 45 + int (*start)(struct ppi_if *ppi); 46 + int (*stop)(struct ppi_if *ppi); 47 + int (*set_params)(struct ppi_if *ppi, struct ppi_params *params); 48 + void (*update_addr)(struct ppi_if *ppi, unsigned long addr); 49 + }; 50 + 51 + enum ppi_type { 52 + PPI_TYPE_PPI, 53 + PPI_TYPE_EPPI, 54 + }; 55 + 56 + struct ppi_info { 57 + enum ppi_type type; 58 + int dma_ch; 59 + int irq_err; 60 + void __iomem *base; 61 + const unsigned short *pin_req; 62 + }; 63 + 64 + struct ppi_if { 65 + unsigned long ppi_control; 66 + const struct ppi_ops *ops; 67 + const struct ppi_info *info; 68 + bool err_int; 69 + void *priv; 70 + }; 71 + 72 + struct ppi_if *ppi_create_instance(const struct ppi_info *info); 73 + void ppi_delete_instance(struct ppi_if *ppi); 74 + #endif