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