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

Configure Feed

Select the types of activity you want to include in your feed.

at v4.5-rc2 1178 lines 32 kB view raw
1/* 2 * Copyright (c) 2011 Atmel Corporation 3 * Josh Wu, <josh.wu@atmel.com> 4 * 5 * Based on previous work by Lars Haring, <lars.haring@atmel.com> 6 * and Sedji Gaouaou 7 * Based on the bttv driver for Bt848 with respective copyright holders 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 14#include <linux/clk.h> 15#include <linux/completion.h> 16#include <linux/delay.h> 17#include <linux/fs.h> 18#include <linux/init.h> 19#include <linux/interrupt.h> 20#include <linux/kernel.h> 21#include <linux/module.h> 22#include <linux/platform_device.h> 23#include <linux/pm_runtime.h> 24#include <linux/slab.h> 25 26#include <media/soc_camera.h> 27#include <media/drv-intf/soc_mediabus.h> 28#include <media/v4l2-of.h> 29#include <media/videobuf2-dma-contig.h> 30 31#include "atmel-isi.h" 32 33#define MAX_BUFFER_NUM 32 34#define MAX_SUPPORT_WIDTH 2048 35#define MAX_SUPPORT_HEIGHT 2048 36#define VID_LIMIT_BYTES (16 * 1024 * 1024) 37#define MIN_FRAME_RATE 15 38#define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE) 39 40/* Frame buffer descriptor */ 41struct fbd { 42 /* Physical address of the frame buffer */ 43 u32 fb_address; 44 /* DMA Control Register(only in HISI2) */ 45 u32 dma_ctrl; 46 /* Physical address of the next fbd */ 47 u32 next_fbd_address; 48}; 49 50static void set_dma_ctrl(struct fbd *fb_desc, u32 ctrl) 51{ 52 fb_desc->dma_ctrl = ctrl; 53} 54 55struct isi_dma_desc { 56 struct list_head list; 57 struct fbd *p_fbd; 58 dma_addr_t fbd_phys; 59}; 60 61/* Frame buffer data */ 62struct frame_buffer { 63 struct vb2_v4l2_buffer vb; 64 struct isi_dma_desc *p_dma_desc; 65 struct list_head list; 66}; 67 68struct atmel_isi { 69 /* Protects the access of variables shared with the ISR */ 70 spinlock_t lock; 71 void __iomem *regs; 72 73 int sequence; 74 75 struct vb2_alloc_ctx *alloc_ctx; 76 77 /* Allocate descriptors for dma buffer use */ 78 struct fbd *p_fb_descriptors; 79 dma_addr_t fb_descriptors_phys; 80 struct list_head dma_desc_head; 81 struct isi_dma_desc dma_desc[MAX_BUFFER_NUM]; 82 bool enable_preview_path; 83 84 struct completion complete; 85 /* ISI peripherial clock */ 86 struct clk *pclk; 87 unsigned int irq; 88 89 struct isi_platform_data pdata; 90 u16 width_flags; /* max 12 bits */ 91 92 struct list_head video_buffer_list; 93 struct frame_buffer *active; 94 95 struct soc_camera_host soc_host; 96}; 97 98static void isi_writel(struct atmel_isi *isi, u32 reg, u32 val) 99{ 100 writel(val, isi->regs + reg); 101} 102static u32 isi_readl(struct atmel_isi *isi, u32 reg) 103{ 104 return readl(isi->regs + reg); 105} 106 107static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, 108 const struct soc_camera_format_xlate *xlate) 109{ 110 if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUYV) { 111 /* all convert to YUYV */ 112 switch (xlate->code) { 113 case MEDIA_BUS_FMT_VYUY8_2X8: 114 return ISI_CFG2_YCC_SWAP_MODE_3; 115 case MEDIA_BUS_FMT_UYVY8_2X8: 116 return ISI_CFG2_YCC_SWAP_MODE_2; 117 case MEDIA_BUS_FMT_YVYU8_2X8: 118 return ISI_CFG2_YCC_SWAP_MODE_1; 119 } 120 } else if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_RGB565) { 121 /* 122 * Preview path is enabled, it will convert UYVY to RGB format. 123 * But if sensor output format is not UYVY, we need to set 124 * YCC_SWAP_MODE to convert it as UYVY. 125 */ 126 switch (xlate->code) { 127 case MEDIA_BUS_FMT_VYUY8_2X8: 128 return ISI_CFG2_YCC_SWAP_MODE_1; 129 case MEDIA_BUS_FMT_YUYV8_2X8: 130 return ISI_CFG2_YCC_SWAP_MODE_2; 131 case MEDIA_BUS_FMT_YVYU8_2X8: 132 return ISI_CFG2_YCC_SWAP_MODE_3; 133 } 134 } 135 136 /* 137 * By default, no swap for the codec path of Atmel ISI. So codec 138 * output is same as sensor's output. 139 * For instance, if sensor's output is YUYV, then codec outputs YUYV. 140 * And if sensor's output is UYVY, then codec outputs UYVY. 141 */ 142 return ISI_CFG2_YCC_SWAP_DEFAULT; 143} 144 145static void configure_geometry(struct atmel_isi *isi, u32 width, 146 u32 height, const struct soc_camera_format_xlate *xlate) 147{ 148 u32 cfg2, psize; 149 u32 fourcc = xlate->host_fmt->fourcc; 150 151 isi->enable_preview_path = fourcc == V4L2_PIX_FMT_RGB565 || 152 fourcc == V4L2_PIX_FMT_RGB32; 153 154 /* According to sensor's output format to set cfg2 */ 155 switch (xlate->code) { 156 default: 157 /* Grey */ 158 case MEDIA_BUS_FMT_Y8_1X8: 159 cfg2 = ISI_CFG2_GRAYSCALE | ISI_CFG2_COL_SPACE_YCbCr; 160 break; 161 /* YUV */ 162 case MEDIA_BUS_FMT_VYUY8_2X8: 163 case MEDIA_BUS_FMT_UYVY8_2X8: 164 case MEDIA_BUS_FMT_YVYU8_2X8: 165 case MEDIA_BUS_FMT_YUYV8_2X8: 166 cfg2 = ISI_CFG2_COL_SPACE_YCbCr | 167 setup_cfg2_yuv_swap(isi, xlate); 168 break; 169 /* RGB, TODO */ 170 } 171 172 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); 173 /* Set width */ 174 cfg2 |= ((width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) & 175 ISI_CFG2_IM_HSIZE_MASK; 176 /* Set height */ 177 cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET) 178 & ISI_CFG2_IM_VSIZE_MASK; 179 isi_writel(isi, ISI_CFG2, cfg2); 180 181 /* No down sampling, preview size equal to sensor output size */ 182 psize = ((width - 1) << ISI_PSIZE_PREV_HSIZE_OFFSET) & 183 ISI_PSIZE_PREV_HSIZE_MASK; 184 psize |= ((height - 1) << ISI_PSIZE_PREV_VSIZE_OFFSET) & 185 ISI_PSIZE_PREV_VSIZE_MASK; 186 isi_writel(isi, ISI_PSIZE, psize); 187 isi_writel(isi, ISI_PDECF, ISI_PDECF_NO_SAMPLING); 188 189 return; 190} 191 192static bool is_supported(struct soc_camera_device *icd, 193 const u32 pixformat) 194{ 195 switch (pixformat) { 196 /* YUV, including grey */ 197 case V4L2_PIX_FMT_GREY: 198 case V4L2_PIX_FMT_YUYV: 199 case V4L2_PIX_FMT_UYVY: 200 case V4L2_PIX_FMT_YVYU: 201 case V4L2_PIX_FMT_VYUY: 202 /* RGB */ 203 case V4L2_PIX_FMT_RGB565: 204 return true; 205 default: 206 return false; 207 } 208} 209 210static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) 211{ 212 if (isi->active) { 213 struct vb2_v4l2_buffer *vbuf = &isi->active->vb; 214 struct frame_buffer *buf = isi->active; 215 216 list_del_init(&buf->list); 217 vbuf->vb2_buf.timestamp = ktime_get_ns(); 218 vbuf->sequence = isi->sequence++; 219 vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE); 220 } 221 222 if (list_empty(&isi->video_buffer_list)) { 223 isi->active = NULL; 224 } else { 225 /* start next dma frame. */ 226 isi->active = list_entry(isi->video_buffer_list.next, 227 struct frame_buffer, list); 228 if (!isi->enable_preview_path) { 229 isi_writel(isi, ISI_DMA_C_DSCR, 230 (u32)isi->active->p_dma_desc->fbd_phys); 231 isi_writel(isi, ISI_DMA_C_CTRL, 232 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); 233 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); 234 } else { 235 isi_writel(isi, ISI_DMA_P_DSCR, 236 (u32)isi->active->p_dma_desc->fbd_phys); 237 isi_writel(isi, ISI_DMA_P_CTRL, 238 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); 239 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH); 240 } 241 } 242 return IRQ_HANDLED; 243} 244 245/* ISI interrupt service routine */ 246static irqreturn_t isi_interrupt(int irq, void *dev_id) 247{ 248 struct atmel_isi *isi = dev_id; 249 u32 status, mask, pending; 250 irqreturn_t ret = IRQ_NONE; 251 252 spin_lock(&isi->lock); 253 254 status = isi_readl(isi, ISI_STATUS); 255 mask = isi_readl(isi, ISI_INTMASK); 256 pending = status & mask; 257 258 if (pending & ISI_CTRL_SRST) { 259 complete(&isi->complete); 260 isi_writel(isi, ISI_INTDIS, ISI_CTRL_SRST); 261 ret = IRQ_HANDLED; 262 } else if (pending & ISI_CTRL_DIS) { 263 complete(&isi->complete); 264 isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS); 265 ret = IRQ_HANDLED; 266 } else { 267 if (likely(pending & ISI_SR_CXFR_DONE) || 268 likely(pending & ISI_SR_PXFR_DONE)) 269 ret = atmel_isi_handle_streaming(isi); 270 } 271 272 spin_unlock(&isi->lock); 273 return ret; 274} 275 276#define WAIT_ISI_RESET 1 277#define WAIT_ISI_DISABLE 0 278static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset) 279{ 280 unsigned long timeout; 281 /* 282 * The reset or disable will only succeed if we have a 283 * pixel clock from the camera. 284 */ 285 init_completion(&isi->complete); 286 287 if (wait_reset) { 288 isi_writel(isi, ISI_INTEN, ISI_CTRL_SRST); 289 isi_writel(isi, ISI_CTRL, ISI_CTRL_SRST); 290 } else { 291 isi_writel(isi, ISI_INTEN, ISI_CTRL_DIS); 292 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); 293 } 294 295 timeout = wait_for_completion_timeout(&isi->complete, 296 msecs_to_jiffies(500)); 297 if (timeout == 0) 298 return -ETIMEDOUT; 299 300 return 0; 301} 302 303/* ------------------------------------------------------------------ 304 Videobuf operations 305 ------------------------------------------------------------------*/ 306static int queue_setup(struct vb2_queue *vq, 307 unsigned int *nbuffers, unsigned int *nplanes, 308 unsigned int sizes[], void *alloc_ctxs[]) 309{ 310 struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 311 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 312 struct atmel_isi *isi = ici->priv; 313 unsigned long size; 314 315 size = icd->sizeimage; 316 317 if (!*nbuffers || *nbuffers > MAX_BUFFER_NUM) 318 *nbuffers = MAX_BUFFER_NUM; 319 320 if (size * *nbuffers > VID_LIMIT_BYTES) 321 *nbuffers = VID_LIMIT_BYTES / size; 322 323 *nplanes = 1; 324 sizes[0] = size; 325 alloc_ctxs[0] = isi->alloc_ctx; 326 327 isi->sequence = 0; 328 isi->active = NULL; 329 330 dev_dbg(icd->parent, "%s, count=%d, size=%ld\n", __func__, 331 *nbuffers, size); 332 333 return 0; 334} 335 336static int buffer_init(struct vb2_buffer *vb) 337{ 338 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 339 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb); 340 341 buf->p_dma_desc = NULL; 342 INIT_LIST_HEAD(&buf->list); 343 344 return 0; 345} 346 347static int buffer_prepare(struct vb2_buffer *vb) 348{ 349 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 350 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); 351 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb); 352 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 353 struct atmel_isi *isi = ici->priv; 354 unsigned long size; 355 struct isi_dma_desc *desc; 356 357 size = icd->sizeimage; 358 359 if (vb2_plane_size(vb, 0) < size) { 360 dev_err(icd->parent, "%s data will not fit into plane (%lu < %lu)\n", 361 __func__, vb2_plane_size(vb, 0), size); 362 return -EINVAL; 363 } 364 365 vb2_set_plane_payload(vb, 0, size); 366 367 if (!buf->p_dma_desc) { 368 if (list_empty(&isi->dma_desc_head)) { 369 dev_err(icd->parent, "Not enough dma descriptors.\n"); 370 return -EINVAL; 371 } else { 372 /* Get an available descriptor */ 373 desc = list_entry(isi->dma_desc_head.next, 374 struct isi_dma_desc, list); 375 /* Delete the descriptor since now it is used */ 376 list_del_init(&desc->list); 377 378 /* Initialize the dma descriptor */ 379 desc->p_fbd->fb_address = 380 vb2_dma_contig_plane_dma_addr(vb, 0); 381 desc->p_fbd->next_fbd_address = 0; 382 set_dma_ctrl(desc->p_fbd, ISI_DMA_CTRL_WB); 383 384 buf->p_dma_desc = desc; 385 } 386 } 387 return 0; 388} 389 390static void buffer_cleanup(struct vb2_buffer *vb) 391{ 392 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 393 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); 394 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 395 struct atmel_isi *isi = ici->priv; 396 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb); 397 398 /* This descriptor is available now and we add to head list */ 399 if (buf->p_dma_desc) 400 list_add(&buf->p_dma_desc->list, &isi->dma_desc_head); 401} 402 403static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer) 404{ 405 u32 ctrl, cfg1; 406 407 cfg1 = isi_readl(isi, ISI_CFG1); 408 /* Enable irq: cxfr for the codec path, pxfr for the preview path */ 409 isi_writel(isi, ISI_INTEN, 410 ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE); 411 412 /* Check if already in a frame */ 413 if (!isi->enable_preview_path) { 414 if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) { 415 dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n"); 416 return; 417 } 418 419 isi_writel(isi, ISI_DMA_C_DSCR, 420 (u32)buffer->p_dma_desc->fbd_phys); 421 isi_writel(isi, ISI_DMA_C_CTRL, 422 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); 423 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); 424 } else { 425 isi_writel(isi, ISI_DMA_P_DSCR, 426 (u32)buffer->p_dma_desc->fbd_phys); 427 isi_writel(isi, ISI_DMA_P_CTRL, 428 ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); 429 isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH); 430 } 431 432 cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK; 433 /* Enable linked list */ 434 cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR; 435 436 /* Enable ISI */ 437 ctrl = ISI_CTRL_EN; 438 439 if (!isi->enable_preview_path) 440 ctrl |= ISI_CTRL_CDC; 441 442 isi_writel(isi, ISI_CTRL, ctrl); 443 isi_writel(isi, ISI_CFG1, cfg1); 444} 445 446static void buffer_queue(struct vb2_buffer *vb) 447{ 448 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 449 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); 450 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 451 struct atmel_isi *isi = ici->priv; 452 struct frame_buffer *buf = container_of(vbuf, struct frame_buffer, vb); 453 unsigned long flags = 0; 454 455 spin_lock_irqsave(&isi->lock, flags); 456 list_add_tail(&buf->list, &isi->video_buffer_list); 457 458 if (isi->active == NULL) { 459 isi->active = buf; 460 if (vb2_is_streaming(vb->vb2_queue)) 461 start_dma(isi, buf); 462 } 463 spin_unlock_irqrestore(&isi->lock, flags); 464} 465 466static int start_streaming(struct vb2_queue *vq, unsigned int count) 467{ 468 struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 469 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 470 struct atmel_isi *isi = ici->priv; 471 int ret; 472 473 pm_runtime_get_sync(ici->v4l2_dev.dev); 474 475 /* Reset ISI */ 476 ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); 477 if (ret < 0) { 478 dev_err(icd->parent, "Reset ISI timed out\n"); 479 pm_runtime_put(ici->v4l2_dev.dev); 480 return ret; 481 } 482 /* Disable all interrupts */ 483 isi_writel(isi, ISI_INTDIS, (u32)~0UL); 484 485 configure_geometry(isi, icd->user_width, icd->user_height, 486 icd->current_fmt); 487 488 spin_lock_irq(&isi->lock); 489 /* Clear any pending interrupt */ 490 isi_readl(isi, ISI_STATUS); 491 492 if (count) 493 start_dma(isi, isi->active); 494 spin_unlock_irq(&isi->lock); 495 496 return 0; 497} 498 499/* abort streaming and wait for last buffer */ 500static void stop_streaming(struct vb2_queue *vq) 501{ 502 struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 503 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 504 struct atmel_isi *isi = ici->priv; 505 struct frame_buffer *buf, *node; 506 int ret = 0; 507 unsigned long timeout; 508 509 spin_lock_irq(&isi->lock); 510 isi->active = NULL; 511 /* Release all active buffers */ 512 list_for_each_entry_safe(buf, node, &isi->video_buffer_list, list) { 513 list_del_init(&buf->list); 514 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); 515 } 516 spin_unlock_irq(&isi->lock); 517 518 if (!isi->enable_preview_path) { 519 timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ; 520 /* Wait until the end of the current frame. */ 521 while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) && 522 time_before(jiffies, timeout)) 523 msleep(1); 524 525 if (time_after(jiffies, timeout)) 526 dev_err(icd->parent, 527 "Timeout waiting for finishing codec request\n"); 528 } 529 530 /* Disable interrupts */ 531 isi_writel(isi, ISI_INTDIS, 532 ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE); 533 534 /* Disable ISI and wait for it is done */ 535 ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); 536 if (ret < 0) 537 dev_err(icd->parent, "Disable ISI timed out\n"); 538 539 pm_runtime_put(ici->v4l2_dev.dev); 540} 541 542static struct vb2_ops isi_video_qops = { 543 .queue_setup = queue_setup, 544 .buf_init = buffer_init, 545 .buf_prepare = buffer_prepare, 546 .buf_cleanup = buffer_cleanup, 547 .buf_queue = buffer_queue, 548 .start_streaming = start_streaming, 549 .stop_streaming = stop_streaming, 550 .wait_prepare = vb2_ops_wait_prepare, 551 .wait_finish = vb2_ops_wait_finish, 552}; 553 554/* ------------------------------------------------------------------ 555 SOC camera operations for the device 556 ------------------------------------------------------------------*/ 557static int isi_camera_init_videobuf(struct vb2_queue *q, 558 struct soc_camera_device *icd) 559{ 560 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 561 562 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 563 q->io_modes = VB2_MMAP; 564 q->drv_priv = icd; 565 q->buf_struct_size = sizeof(struct frame_buffer); 566 q->ops = &isi_video_qops; 567 q->mem_ops = &vb2_dma_contig_memops; 568 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 569 q->lock = &ici->host_lock; 570 571 return vb2_queue_init(q); 572} 573 574static int isi_camera_set_fmt(struct soc_camera_device *icd, 575 struct v4l2_format *f) 576{ 577 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 578 const struct soc_camera_format_xlate *xlate; 579 struct v4l2_pix_format *pix = &f->fmt.pix; 580 struct v4l2_subdev_format format = { 581 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 582 }; 583 struct v4l2_mbus_framefmt *mf = &format.format; 584 int ret; 585 586 /* check with atmel-isi support format, if not support use YUYV */ 587 if (!is_supported(icd, pix->pixelformat)) 588 pix->pixelformat = V4L2_PIX_FMT_YUYV; 589 590 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 591 if (!xlate) { 592 dev_warn(icd->parent, "Format %x not found\n", 593 pix->pixelformat); 594 return -EINVAL; 595 } 596 597 dev_dbg(icd->parent, "Plan to set format %dx%d\n", 598 pix->width, pix->height); 599 600 mf->width = pix->width; 601 mf->height = pix->height; 602 mf->field = pix->field; 603 mf->colorspace = pix->colorspace; 604 mf->code = xlate->code; 605 606 ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &format); 607 if (ret < 0) 608 return ret; 609 610 if (mf->code != xlate->code) 611 return -EINVAL; 612 613 pix->width = mf->width; 614 pix->height = mf->height; 615 pix->field = mf->field; 616 pix->colorspace = mf->colorspace; 617 icd->current_fmt = xlate; 618 619 dev_dbg(icd->parent, "Finally set format %dx%d\n", 620 pix->width, pix->height); 621 622 return ret; 623} 624 625static int isi_camera_try_fmt(struct soc_camera_device *icd, 626 struct v4l2_format *f) 627{ 628 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 629 const struct soc_camera_format_xlate *xlate; 630 struct v4l2_pix_format *pix = &f->fmt.pix; 631 struct v4l2_subdev_pad_config pad_cfg; 632 struct v4l2_subdev_format format = { 633 .which = V4L2_SUBDEV_FORMAT_TRY, 634 }; 635 struct v4l2_mbus_framefmt *mf = &format.format; 636 u32 pixfmt = pix->pixelformat; 637 int ret; 638 639 /* check with atmel-isi support format, if not support use YUYV */ 640 if (!is_supported(icd, pix->pixelformat)) 641 pix->pixelformat = V4L2_PIX_FMT_YUYV; 642 643 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 644 if (pixfmt && !xlate) { 645 dev_warn(icd->parent, "Format %x not found\n", pixfmt); 646 return -EINVAL; 647 } 648 649 /* limit to Atmel ISI hardware capabilities */ 650 if (pix->height > MAX_SUPPORT_HEIGHT) 651 pix->height = MAX_SUPPORT_HEIGHT; 652 if (pix->width > MAX_SUPPORT_WIDTH) 653 pix->width = MAX_SUPPORT_WIDTH; 654 655 /* limit to sensor capabilities */ 656 mf->width = pix->width; 657 mf->height = pix->height; 658 mf->field = pix->field; 659 mf->colorspace = pix->colorspace; 660 mf->code = xlate->code; 661 662 ret = v4l2_subdev_call(sd, pad, set_fmt, &pad_cfg, &format); 663 if (ret < 0) 664 return ret; 665 666 pix->width = mf->width; 667 pix->height = mf->height; 668 pix->colorspace = mf->colorspace; 669 670 switch (mf->field) { 671 case V4L2_FIELD_ANY: 672 pix->field = V4L2_FIELD_NONE; 673 break; 674 case V4L2_FIELD_NONE: 675 break; 676 default: 677 dev_err(icd->parent, "Field type %d unsupported.\n", 678 mf->field); 679 ret = -EINVAL; 680 } 681 682 return ret; 683} 684 685static const struct soc_mbus_pixelfmt isi_camera_formats[] = { 686 { 687 .fourcc = V4L2_PIX_FMT_YUYV, 688 .name = "Packed YUV422 16 bit", 689 .bits_per_sample = 8, 690 .packing = SOC_MBUS_PACKING_2X8_PADHI, 691 .order = SOC_MBUS_ORDER_LE, 692 .layout = SOC_MBUS_LAYOUT_PACKED, 693 }, 694 { 695 .fourcc = V4L2_PIX_FMT_RGB565, 696 .name = "RGB565", 697 .bits_per_sample = 8, 698 .packing = SOC_MBUS_PACKING_2X8_PADHI, 699 .order = SOC_MBUS_ORDER_LE, 700 .layout = SOC_MBUS_LAYOUT_PACKED, 701 }, 702}; 703 704/* This will be corrected as we get more formats */ 705static bool isi_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) 706{ 707 return fmt->packing == SOC_MBUS_PACKING_NONE || 708 (fmt->bits_per_sample == 8 && 709 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || 710 (fmt->bits_per_sample > 8 && 711 fmt->packing == SOC_MBUS_PACKING_EXTEND16); 712} 713 714#define ISI_BUS_PARAM (V4L2_MBUS_MASTER | \ 715 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \ 716 V4L2_MBUS_HSYNC_ACTIVE_LOW | \ 717 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \ 718 V4L2_MBUS_VSYNC_ACTIVE_LOW | \ 719 V4L2_MBUS_PCLK_SAMPLE_RISING | \ 720 V4L2_MBUS_PCLK_SAMPLE_FALLING | \ 721 V4L2_MBUS_DATA_ACTIVE_HIGH) 722 723static int isi_camera_try_bus_param(struct soc_camera_device *icd, 724 unsigned char buswidth) 725{ 726 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 727 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 728 struct atmel_isi *isi = ici->priv; 729 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; 730 unsigned long common_flags; 731 int ret; 732 733 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg); 734 if (!ret) { 735 common_flags = soc_mbus_config_compatible(&cfg, 736 ISI_BUS_PARAM); 737 if (!common_flags) { 738 dev_warn(icd->parent, 739 "Flags incompatible: camera 0x%x, host 0x%x\n", 740 cfg.flags, ISI_BUS_PARAM); 741 return -EINVAL; 742 } 743 } else if (ret != -ENOIOCTLCMD) { 744 return ret; 745 } 746 747 if ((1 << (buswidth - 1)) & isi->width_flags) 748 return 0; 749 return -EINVAL; 750} 751 752 753static int isi_camera_get_formats(struct soc_camera_device *icd, 754 unsigned int idx, 755 struct soc_camera_format_xlate *xlate) 756{ 757 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 758 int formats = 0, ret, i, n; 759 /* sensor format */ 760 struct v4l2_subdev_mbus_code_enum code = { 761 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 762 .index = idx, 763 }; 764 /* soc camera host format */ 765 const struct soc_mbus_pixelfmt *fmt; 766 767 ret = v4l2_subdev_call(sd, pad, enum_mbus_code, NULL, &code); 768 if (ret < 0) 769 /* No more formats */ 770 return 0; 771 772 fmt = soc_mbus_get_fmtdesc(code.code); 773 if (!fmt) { 774 dev_err(icd->parent, 775 "Invalid format code #%u: %d\n", idx, code.code); 776 return 0; 777 } 778 779 /* This also checks support for the requested bits-per-sample */ 780 ret = isi_camera_try_bus_param(icd, fmt->bits_per_sample); 781 if (ret < 0) { 782 dev_err(icd->parent, 783 "Fail to try the bus parameters.\n"); 784 return 0; 785 } 786 787 switch (code.code) { 788 case MEDIA_BUS_FMT_UYVY8_2X8: 789 case MEDIA_BUS_FMT_VYUY8_2X8: 790 case MEDIA_BUS_FMT_YUYV8_2X8: 791 case MEDIA_BUS_FMT_YVYU8_2X8: 792 n = ARRAY_SIZE(isi_camera_formats); 793 formats += n; 794 for (i = 0; xlate && i < n; i++, xlate++) { 795 xlate->host_fmt = &isi_camera_formats[i]; 796 xlate->code = code.code; 797 dev_dbg(icd->parent, "Providing format %s using code %d\n", 798 isi_camera_formats[0].name, code.code); 799 } 800 break; 801 default: 802 if (!isi_camera_packing_supported(fmt)) 803 return 0; 804 if (xlate) 805 dev_dbg(icd->parent, 806 "Providing format %s in pass-through mode\n", 807 fmt->name); 808 } 809 810 /* Generic pass-through */ 811 formats++; 812 if (xlate) { 813 xlate->host_fmt = fmt; 814 xlate->code = code.code; 815 xlate++; 816 } 817 818 return formats; 819} 820 821static int isi_camera_add_device(struct soc_camera_device *icd) 822{ 823 dev_dbg(icd->parent, "Atmel ISI Camera driver attached to camera %d\n", 824 icd->devnum); 825 826 return 0; 827} 828 829static void isi_camera_remove_device(struct soc_camera_device *icd) 830{ 831 dev_dbg(icd->parent, "Atmel ISI Camera driver detached from camera %d\n", 832 icd->devnum); 833} 834 835static unsigned int isi_camera_poll(struct file *file, poll_table *pt) 836{ 837 struct soc_camera_device *icd = file->private_data; 838 839 return vb2_poll(&icd->vb2_vidq, file, pt); 840} 841 842static int isi_camera_querycap(struct soc_camera_host *ici, 843 struct v4l2_capability *cap) 844{ 845 strcpy(cap->driver, "atmel-isi"); 846 strcpy(cap->card, "Atmel Image Sensor Interface"); 847 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; 848 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; 849 850 return 0; 851} 852 853static int isi_camera_set_bus_param(struct soc_camera_device *icd) 854{ 855 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 856 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 857 struct atmel_isi *isi = ici->priv; 858 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; 859 unsigned long common_flags; 860 int ret; 861 u32 cfg1 = 0; 862 863 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg); 864 if (!ret) { 865 common_flags = soc_mbus_config_compatible(&cfg, 866 ISI_BUS_PARAM); 867 if (!common_flags) { 868 dev_warn(icd->parent, 869 "Flags incompatible: camera 0x%x, host 0x%x\n", 870 cfg.flags, ISI_BUS_PARAM); 871 return -EINVAL; 872 } 873 } else if (ret != -ENOIOCTLCMD) { 874 return ret; 875 } else { 876 common_flags = ISI_BUS_PARAM; 877 } 878 dev_dbg(icd->parent, "Flags cam: 0x%x host: 0x%x common: 0x%lx\n", 879 cfg.flags, ISI_BUS_PARAM, common_flags); 880 881 /* Make choises, based on platform preferences */ 882 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) && 883 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) { 884 if (isi->pdata.hsync_act_low) 885 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH; 886 else 887 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW; 888 } 889 890 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) && 891 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) { 892 if (isi->pdata.vsync_act_low) 893 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH; 894 else 895 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW; 896 } 897 898 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) && 899 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) { 900 if (isi->pdata.pclk_act_falling) 901 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING; 902 else 903 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING; 904 } 905 906 cfg.flags = common_flags; 907 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg); 908 if (ret < 0 && ret != -ENOIOCTLCMD) { 909 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n", 910 common_flags, ret); 911 return ret; 912 } 913 914 /* set bus param for ISI */ 915 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) 916 cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW; 917 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) 918 cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW; 919 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) 920 cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING; 921 922 dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix clock %s edge\n", 923 common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high", 924 common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high", 925 common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising"); 926 927 if (isi->pdata.has_emb_sync) 928 cfg1 |= ISI_CFG1_EMB_SYNC; 929 if (isi->pdata.full_mode) 930 cfg1 |= ISI_CFG1_FULL_MODE; 931 932 cfg1 |= ISI_CFG1_THMASK_BEATS_16; 933 934 /* Enable PM and peripheral clock before operate isi registers */ 935 pm_runtime_get_sync(ici->v4l2_dev.dev); 936 937 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); 938 isi_writel(isi, ISI_CFG1, cfg1); 939 940 pm_runtime_put(ici->v4l2_dev.dev); 941 942 return 0; 943} 944 945static struct soc_camera_host_ops isi_soc_camera_host_ops = { 946 .owner = THIS_MODULE, 947 .add = isi_camera_add_device, 948 .remove = isi_camera_remove_device, 949 .set_fmt = isi_camera_set_fmt, 950 .try_fmt = isi_camera_try_fmt, 951 .get_formats = isi_camera_get_formats, 952 .init_videobuf2 = isi_camera_init_videobuf, 953 .poll = isi_camera_poll, 954 .querycap = isi_camera_querycap, 955 .set_bus_param = isi_camera_set_bus_param, 956}; 957 958/* -----------------------------------------------------------------------*/ 959static int atmel_isi_remove(struct platform_device *pdev) 960{ 961 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); 962 struct atmel_isi *isi = container_of(soc_host, 963 struct atmel_isi, soc_host); 964 965 soc_camera_host_unregister(soc_host); 966 vb2_dma_contig_cleanup_ctx(isi->alloc_ctx); 967 dma_free_coherent(&pdev->dev, 968 sizeof(struct fbd) * MAX_BUFFER_NUM, 969 isi->p_fb_descriptors, 970 isi->fb_descriptors_phys); 971 pm_runtime_disable(&pdev->dev); 972 973 return 0; 974} 975 976static int atmel_isi_parse_dt(struct atmel_isi *isi, 977 struct platform_device *pdev) 978{ 979 struct device_node *np= pdev->dev.of_node; 980 struct v4l2_of_endpoint ep; 981 int err; 982 983 /* Default settings for ISI */ 984 isi->pdata.full_mode = 1; 985 isi->pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL; 986 987 np = of_graph_get_next_endpoint(np, NULL); 988 if (!np) { 989 dev_err(&pdev->dev, "Could not find the endpoint\n"); 990 return -EINVAL; 991 } 992 993 err = v4l2_of_parse_endpoint(np, &ep); 994 of_node_put(np); 995 if (err) { 996 dev_err(&pdev->dev, "Could not parse the endpoint\n"); 997 return err; 998 } 999 1000 switch (ep.bus.parallel.bus_width) { 1001 case 8: 1002 isi->pdata.data_width_flags = ISI_DATAWIDTH_8; 1003 break; 1004 case 10: 1005 isi->pdata.data_width_flags = 1006 ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10; 1007 break; 1008 default: 1009 dev_err(&pdev->dev, "Unsupported bus width: %d\n", 1010 ep.bus.parallel.bus_width); 1011 return -EINVAL; 1012 } 1013 1014 if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) 1015 isi->pdata.hsync_act_low = true; 1016 if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) 1017 isi->pdata.vsync_act_low = true; 1018 if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) 1019 isi->pdata.pclk_act_falling = true; 1020 1021 if (ep.bus_type == V4L2_MBUS_BT656) 1022 isi->pdata.has_emb_sync = true; 1023 1024 return 0; 1025} 1026 1027static int atmel_isi_probe(struct platform_device *pdev) 1028{ 1029 unsigned int irq; 1030 struct atmel_isi *isi; 1031 struct resource *regs; 1032 int ret, i; 1033 struct soc_camera_host *soc_host; 1034 1035 isi = devm_kzalloc(&pdev->dev, sizeof(struct atmel_isi), GFP_KERNEL); 1036 if (!isi) { 1037 dev_err(&pdev->dev, "Can't allocate interface!\n"); 1038 return -ENOMEM; 1039 } 1040 1041 isi->pclk = devm_clk_get(&pdev->dev, "isi_clk"); 1042 if (IS_ERR(isi->pclk)) 1043 return PTR_ERR(isi->pclk); 1044 1045 ret = atmel_isi_parse_dt(isi, pdev); 1046 if (ret) 1047 return ret; 1048 1049 isi->active = NULL; 1050 spin_lock_init(&isi->lock); 1051 INIT_LIST_HEAD(&isi->video_buffer_list); 1052 INIT_LIST_HEAD(&isi->dma_desc_head); 1053 1054 isi->p_fb_descriptors = dma_alloc_coherent(&pdev->dev, 1055 sizeof(struct fbd) * MAX_BUFFER_NUM, 1056 &isi->fb_descriptors_phys, 1057 GFP_KERNEL); 1058 if (!isi->p_fb_descriptors) { 1059 dev_err(&pdev->dev, "Can't allocate descriptors!\n"); 1060 return -ENOMEM; 1061 } 1062 1063 for (i = 0; i < MAX_BUFFER_NUM; i++) { 1064 isi->dma_desc[i].p_fbd = isi->p_fb_descriptors + i; 1065 isi->dma_desc[i].fbd_phys = isi->fb_descriptors_phys + 1066 i * sizeof(struct fbd); 1067 list_add(&isi->dma_desc[i].list, &isi->dma_desc_head); 1068 } 1069 1070 isi->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); 1071 if (IS_ERR(isi->alloc_ctx)) { 1072 ret = PTR_ERR(isi->alloc_ctx); 1073 goto err_alloc_ctx; 1074 } 1075 1076 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1077 isi->regs = devm_ioremap_resource(&pdev->dev, regs); 1078 if (IS_ERR(isi->regs)) { 1079 ret = PTR_ERR(isi->regs); 1080 goto err_ioremap; 1081 } 1082 1083 if (isi->pdata.data_width_flags & ISI_DATAWIDTH_8) 1084 isi->width_flags = 1 << 7; 1085 if (isi->pdata.data_width_flags & ISI_DATAWIDTH_10) 1086 isi->width_flags |= 1 << 9; 1087 1088 irq = platform_get_irq(pdev, 0); 1089 if (IS_ERR_VALUE(irq)) { 1090 ret = irq; 1091 goto err_req_irq; 1092 } 1093 1094 ret = devm_request_irq(&pdev->dev, irq, isi_interrupt, 0, "isi", isi); 1095 if (ret) { 1096 dev_err(&pdev->dev, "Unable to request irq %d\n", irq); 1097 goto err_req_irq; 1098 } 1099 isi->irq = irq; 1100 1101 soc_host = &isi->soc_host; 1102 soc_host->drv_name = "isi-camera"; 1103 soc_host->ops = &isi_soc_camera_host_ops; 1104 soc_host->priv = isi; 1105 soc_host->v4l2_dev.dev = &pdev->dev; 1106 soc_host->nr = pdev->id; 1107 1108 pm_suspend_ignore_children(&pdev->dev, true); 1109 pm_runtime_enable(&pdev->dev); 1110 1111 ret = soc_camera_host_register(soc_host); 1112 if (ret) { 1113 dev_err(&pdev->dev, "Unable to register soc camera host\n"); 1114 goto err_register_soc_camera_host; 1115 } 1116 return 0; 1117 1118err_register_soc_camera_host: 1119 pm_runtime_disable(&pdev->dev); 1120err_req_irq: 1121err_ioremap: 1122 vb2_dma_contig_cleanup_ctx(isi->alloc_ctx); 1123err_alloc_ctx: 1124 dma_free_coherent(&pdev->dev, 1125 sizeof(struct fbd) * MAX_BUFFER_NUM, 1126 isi->p_fb_descriptors, 1127 isi->fb_descriptors_phys); 1128 1129 return ret; 1130} 1131 1132#ifdef CONFIG_PM 1133static int atmel_isi_runtime_suspend(struct device *dev) 1134{ 1135 struct soc_camera_host *soc_host = to_soc_camera_host(dev); 1136 struct atmel_isi *isi = container_of(soc_host, 1137 struct atmel_isi, soc_host); 1138 1139 clk_disable_unprepare(isi->pclk); 1140 1141 return 0; 1142} 1143static int atmel_isi_runtime_resume(struct device *dev) 1144{ 1145 struct soc_camera_host *soc_host = to_soc_camera_host(dev); 1146 struct atmel_isi *isi = container_of(soc_host, 1147 struct atmel_isi, soc_host); 1148 1149 return clk_prepare_enable(isi->pclk); 1150} 1151#endif /* CONFIG_PM */ 1152 1153static const struct dev_pm_ops atmel_isi_dev_pm_ops = { 1154 SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend, 1155 atmel_isi_runtime_resume, NULL) 1156}; 1157 1158static const struct of_device_id atmel_isi_of_match[] = { 1159 { .compatible = "atmel,at91sam9g45-isi" }, 1160 { } 1161}; 1162MODULE_DEVICE_TABLE(of, atmel_isi_of_match); 1163 1164static struct platform_driver atmel_isi_driver = { 1165 .remove = atmel_isi_remove, 1166 .driver = { 1167 .name = "atmel_isi", 1168 .of_match_table = of_match_ptr(atmel_isi_of_match), 1169 .pm = &atmel_isi_dev_pm_ops, 1170 }, 1171}; 1172 1173module_platform_driver_probe(atmel_isi_driver, atmel_isi_probe); 1174 1175MODULE_AUTHOR("Josh Wu <josh.wu@atmel.com>"); 1176MODULE_DESCRIPTION("The V4L2 driver for Atmel Linux"); 1177MODULE_LICENSE("GPL"); 1178MODULE_SUPPORTED_DEVICE("video");