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