imx7-media-csi.c (33697B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * V4L2 Capture CSI Subdev for Freescale i.MX6UL/L / i.MX7 SOC 4 * 5 * Copyright (c) 2019 Linaro Ltd 6 * 7 */ 8 9#include <linux/clk.h> 10#include <linux/delay.h> 11#include <linux/gcd.h> 12#include <linux/interrupt.h> 13#include <linux/mfd/syscon.h> 14#include <linux/module.h> 15#include <linux/of_device.h> 16#include <linux/of_graph.h> 17#include <linux/pinctrl/consumer.h> 18#include <linux/platform_device.h> 19#include <linux/regmap.h> 20#include <linux/types.h> 21 22#include <media/v4l2-device.h> 23#include <media/v4l2-event.h> 24#include <media/v4l2-fwnode.h> 25#include <media/v4l2-mc.h> 26#include <media/v4l2-subdev.h> 27#include <media/videobuf2-dma-contig.h> 28 29#include <media/imx.h> 30#include "imx-media.h" 31 32#define IMX7_CSI_PAD_SINK 0 33#define IMX7_CSI_PAD_SRC 1 34#define IMX7_CSI_PADS_NUM 2 35 36/* csi control reg 1 */ 37#define BIT_SWAP16_EN BIT(31) 38#define BIT_EXT_VSYNC BIT(30) 39#define BIT_EOF_INT_EN BIT(29) 40#define BIT_PRP_IF_EN BIT(28) 41#define BIT_CCIR_MODE BIT(27) 42#define BIT_COF_INT_EN BIT(26) 43#define BIT_SF_OR_INTEN BIT(25) 44#define BIT_RF_OR_INTEN BIT(24) 45#define BIT_SFF_DMA_DONE_INTEN BIT(22) 46#define BIT_STATFF_INTEN BIT(21) 47#define BIT_FB2_DMA_DONE_INTEN BIT(20) 48#define BIT_FB1_DMA_DONE_INTEN BIT(19) 49#define BIT_RXFF_INTEN BIT(18) 50#define BIT_SOF_POL BIT(17) 51#define BIT_SOF_INTEN BIT(16) 52#define BIT_MCLKDIV(n) ((n) << 12) 53#define BIT_MCLKDIV_MASK (0xf << 12) 54#define BIT_HSYNC_POL BIT(11) 55#define BIT_CCIR_EN BIT(10) 56#define BIT_MCLKEN BIT(9) 57#define BIT_FCC BIT(8) 58#define BIT_PACK_DIR BIT(7) 59#define BIT_CLR_STATFIFO BIT(6) 60#define BIT_CLR_RXFIFO BIT(5) 61#define BIT_GCLK_MODE BIT(4) 62#define BIT_INV_DATA BIT(3) 63#define BIT_INV_PCLK BIT(2) 64#define BIT_REDGE BIT(1) 65#define BIT_PIXEL_BIT BIT(0) 66 67/* control reg 2 */ 68#define BIT_DMA_BURST_TYPE_RFF_INCR4 (1 << 30) 69#define BIT_DMA_BURST_TYPE_RFF_INCR8 (2 << 30) 70#define BIT_DMA_BURST_TYPE_RFF_INCR16 (3 << 30) 71#define BIT_DMA_BURST_TYPE_RFF_MASK (3 << 30) 72 73/* control reg 3 */ 74#define BIT_FRMCNT(n) ((n) << 16) 75#define BIT_FRMCNT_MASK (0xffff << 16) 76#define BIT_FRMCNT_RST BIT(15) 77#define BIT_DMA_REFLASH_RFF BIT(14) 78#define BIT_DMA_REFLASH_SFF BIT(13) 79#define BIT_DMA_REQ_EN_RFF BIT(12) 80#define BIT_DMA_REQ_EN_SFF BIT(11) 81#define BIT_STATFF_LEVEL(n) ((n) << 8) 82#define BIT_STATFF_LEVEL_MASK (0x7 << 8) 83#define BIT_HRESP_ERR_EN BIT(7) 84#define BIT_RXFF_LEVEL(n) ((n) << 4) 85#define BIT_RXFF_LEVEL_MASK (0x7 << 4) 86#define BIT_TWO_8BIT_SENSOR BIT(3) 87#define BIT_ZERO_PACK_EN BIT(2) 88#define BIT_ECC_INT_EN BIT(1) 89#define BIT_ECC_AUTO_EN BIT(0) 90 91/* csi status reg */ 92#define BIT_ADDR_CH_ERR_INT BIT(28) 93#define BIT_FIELD0_INT BIT(27) 94#define BIT_FIELD1_INT BIT(26) 95#define BIT_SFF_OR_INT BIT(25) 96#define BIT_RFF_OR_INT BIT(24) 97#define BIT_DMA_TSF_DONE_SFF BIT(22) 98#define BIT_STATFF_INT BIT(21) 99#define BIT_DMA_TSF_DONE_FB2 BIT(20) 100#define BIT_DMA_TSF_DONE_FB1 BIT(19) 101#define BIT_RXFF_INT BIT(18) 102#define BIT_EOF_INT BIT(17) 103#define BIT_SOF_INT BIT(16) 104#define BIT_F2_INT BIT(15) 105#define BIT_F1_INT BIT(14) 106#define BIT_COF_INT BIT(13) 107#define BIT_HRESP_ERR_INT BIT(7) 108#define BIT_ECC_INT BIT(1) 109#define BIT_DRDY BIT(0) 110 111/* csi image parameter reg */ 112#define BIT_IMAGE_WIDTH(n) ((n) << 16) 113#define BIT_IMAGE_HEIGHT(n) (n) 114 115/* csi control reg 18 */ 116#define BIT_CSI_HW_ENABLE BIT(31) 117#define BIT_MIPI_DATA_FORMAT_RAW8 (0x2a << 25) 118#define BIT_MIPI_DATA_FORMAT_RAW10 (0x2b << 25) 119#define BIT_MIPI_DATA_FORMAT_RAW12 (0x2c << 25) 120#define BIT_MIPI_DATA_FORMAT_RAW14 (0x2d << 25) 121#define BIT_MIPI_DATA_FORMAT_YUV422_8B (0x1e << 25) 122#define BIT_MIPI_DATA_FORMAT_MASK (0x3f << 25) 123#define BIT_DATA_FROM_MIPI BIT(22) 124#define BIT_MIPI_YU_SWAP BIT(21) 125#define BIT_MIPI_DOUBLE_CMPNT BIT(20) 126#define BIT_MASK_OPTION_FIRST_FRAME (0 << 18) 127#define BIT_MASK_OPTION_CSI_EN (1 << 18) 128#define BIT_MASK_OPTION_SECOND_FRAME (2 << 18) 129#define BIT_MASK_OPTION_ON_DATA (3 << 18) 130#define BIT_BASEADDR_CHG_ERR_EN BIT(9) 131#define BIT_BASEADDR_SWITCH_SEL BIT(5) 132#define BIT_BASEADDR_SWITCH_EN BIT(4) 133#define BIT_PARALLEL24_EN BIT(3) 134#define BIT_DEINTERLACE_EN BIT(2) 135#define BIT_TVDECODER_IN_EN BIT(1) 136#define BIT_NTSC_EN BIT(0) 137 138#define CSI_MCLK_VF 1 139#define CSI_MCLK_ENC 2 140#define CSI_MCLK_RAW 4 141#define CSI_MCLK_I2C 8 142 143#define CSI_CSICR1 0x00 144#define CSI_CSICR2 0x04 145#define CSI_CSICR3 0x08 146#define CSI_STATFIFO 0x0c 147#define CSI_CSIRXFIFO 0x10 148#define CSI_CSIRXCNT 0x14 149#define CSI_CSISR 0x18 150 151#define CSI_CSIDBG 0x1c 152#define CSI_CSIDMASA_STATFIFO 0x20 153#define CSI_CSIDMATS_STATFIFO 0x24 154#define CSI_CSIDMASA_FB1 0x28 155#define CSI_CSIDMASA_FB2 0x2c 156#define CSI_CSIFBUF_PARA 0x30 157#define CSI_CSIIMAG_PARA 0x34 158 159#define CSI_CSICR18 0x48 160#define CSI_CSICR19 0x4c 161 162enum imx_csi_model { 163 IMX7_CSI_IMX7 = 0, 164 IMX7_CSI_IMX8MQ, 165}; 166 167struct imx7_csi { 168 struct device *dev; 169 struct v4l2_subdev sd; 170 struct v4l2_async_notifier notifier; 171 struct imx_media_video_dev *vdev; 172 struct imx_media_dev *imxmd; 173 struct media_pad pad[IMX7_CSI_PADS_NUM]; 174 175 /* lock to protect members below */ 176 struct mutex lock; 177 /* lock to protect irq handler when stop streaming */ 178 spinlock_t irqlock; 179 180 struct v4l2_subdev *src_sd; 181 182 struct v4l2_mbus_framefmt format_mbus[IMX7_CSI_PADS_NUM]; 183 const struct imx_media_pixfmt *cc[IMX7_CSI_PADS_NUM]; 184 struct v4l2_fract frame_interval[IMX7_CSI_PADS_NUM]; 185 186 void __iomem *regbase; 187 int irq; 188 struct clk *mclk; 189 190 /* active vb2 buffers to send to video dev sink */ 191 struct imx_media_buffer *active_vb2_buf[2]; 192 struct imx_media_dma_buf underrun_buf; 193 194 int buf_num; 195 u32 frame_sequence; 196 197 bool last_eof; 198 bool is_streaming; 199 bool is_csi2; 200 201 struct completion last_eof_completion; 202 203 enum imx_csi_model model; 204}; 205 206static struct imx7_csi * 207imx7_csi_notifier_to_dev(struct v4l2_async_notifier *n) 208{ 209 return container_of(n, struct imx7_csi, notifier); 210} 211 212/* ----------------------------------------------------------------------------- 213 * Hardware Configuration 214 */ 215 216static u32 imx7_csi_reg_read(struct imx7_csi *csi, unsigned int offset) 217{ 218 return readl(csi->regbase + offset); 219} 220 221static void imx7_csi_reg_write(struct imx7_csi *csi, unsigned int value, 222 unsigned int offset) 223{ 224 writel(value, csi->regbase + offset); 225} 226 227static u32 imx7_csi_irq_clear(struct imx7_csi *csi) 228{ 229 u32 isr; 230 231 isr = imx7_csi_reg_read(csi, CSI_CSISR); 232 imx7_csi_reg_write(csi, isr, CSI_CSISR); 233 234 return isr; 235} 236 237static void imx7_csi_init_default(struct imx7_csi *csi) 238{ 239 imx7_csi_reg_write(csi, BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE | 240 BIT_HSYNC_POL | BIT_FCC | BIT_MCLKDIV(1) | 241 BIT_MCLKEN, CSI_CSICR1); 242 imx7_csi_reg_write(csi, 0, CSI_CSICR2); 243 imx7_csi_reg_write(csi, BIT_FRMCNT_RST, CSI_CSICR3); 244 245 imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(800) | BIT_IMAGE_HEIGHT(600), 246 CSI_CSIIMAG_PARA); 247 248 imx7_csi_reg_write(csi, BIT_DMA_REFLASH_RFF, CSI_CSICR3); 249} 250 251static void imx7_csi_hw_enable_irq(struct imx7_csi *csi) 252{ 253 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); 254 255 cr1 |= BIT_RFF_OR_INT; 256 cr1 |= BIT_FB1_DMA_DONE_INTEN; 257 cr1 |= BIT_FB2_DMA_DONE_INTEN; 258 259 imx7_csi_reg_write(csi, cr1, CSI_CSICR1); 260} 261 262static void imx7_csi_hw_disable_irq(struct imx7_csi *csi) 263{ 264 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); 265 266 cr1 &= ~BIT_RFF_OR_INT; 267 cr1 &= ~BIT_FB1_DMA_DONE_INTEN; 268 cr1 &= ~BIT_FB2_DMA_DONE_INTEN; 269 270 imx7_csi_reg_write(csi, cr1, CSI_CSICR1); 271} 272 273static void imx7_csi_hw_enable(struct imx7_csi *csi) 274{ 275 u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18); 276 277 cr |= BIT_CSI_HW_ENABLE; 278 279 imx7_csi_reg_write(csi, cr, CSI_CSICR18); 280} 281 282static void imx7_csi_hw_disable(struct imx7_csi *csi) 283{ 284 u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18); 285 286 cr &= ~BIT_CSI_HW_ENABLE; 287 288 imx7_csi_reg_write(csi, cr, CSI_CSICR18); 289} 290 291static void imx7_csi_dma_reflash(struct imx7_csi *csi) 292{ 293 u32 cr3; 294 295 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3); 296 cr3 |= BIT_DMA_REFLASH_RFF; 297 imx7_csi_reg_write(csi, cr3, CSI_CSICR3); 298} 299 300static void imx7_csi_rx_fifo_clear(struct imx7_csi *csi) 301{ 302 u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1) & ~BIT_FCC; 303 304 imx7_csi_reg_write(csi, cr1, CSI_CSICR1); 305 imx7_csi_reg_write(csi, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1); 306 imx7_csi_reg_write(csi, cr1 | BIT_FCC, CSI_CSICR1); 307} 308 309static void imx7_csi_dmareq_rff_enable(struct imx7_csi *csi) 310{ 311 u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3); 312 313 cr3 |= BIT_DMA_REQ_EN_RFF; 314 cr3 |= BIT_HRESP_ERR_EN; 315 cr3 &= ~BIT_RXFF_LEVEL_MASK; 316 cr3 |= BIT_RXFF_LEVEL(2); 317 318 imx7_csi_reg_write(csi, cr3, CSI_CSICR3); 319} 320 321static void imx7_csi_dmareq_rff_disable(struct imx7_csi *csi) 322{ 323 u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3); 324 325 cr3 &= ~BIT_DMA_REQ_EN_RFF; 326 cr3 &= ~BIT_HRESP_ERR_EN; 327 imx7_csi_reg_write(csi, cr3, CSI_CSICR3); 328} 329 330static void imx7_csi_update_buf(struct imx7_csi *csi, dma_addr_t phys, 331 int buf_num) 332{ 333 if (buf_num == 1) 334 imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB2); 335 else 336 imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB1); 337} 338 339static void imx7_csi_setup_vb2_buf(struct imx7_csi *csi) 340{ 341 struct imx_media_video_dev *vdev = csi->vdev; 342 struct imx_media_buffer *buf; 343 struct vb2_buffer *vb2_buf; 344 dma_addr_t phys[2]; 345 int i; 346 347 for (i = 0; i < 2; i++) { 348 buf = imx_media_capture_device_next_buf(vdev); 349 if (buf) { 350 csi->active_vb2_buf[i] = buf; 351 vb2_buf = &buf->vbuf.vb2_buf; 352 phys[i] = vb2_dma_contig_plane_dma_addr(vb2_buf, 0); 353 } else { 354 csi->active_vb2_buf[i] = NULL; 355 phys[i] = csi->underrun_buf.phys; 356 } 357 358 imx7_csi_update_buf(csi, phys[i], i); 359 } 360} 361 362static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi, 363 enum vb2_buffer_state return_status) 364{ 365 struct imx_media_buffer *buf; 366 int i; 367 368 /* return any remaining active frames with return_status */ 369 for (i = 0; i < 2; i++) { 370 buf = csi->active_vb2_buf[i]; 371 if (buf) { 372 struct vb2_buffer *vb = &buf->vbuf.vb2_buf; 373 374 vb->timestamp = ktime_get_ns(); 375 vb2_buffer_done(vb, return_status); 376 csi->active_vb2_buf[i] = NULL; 377 } 378 } 379} 380 381static int imx7_csi_dma_setup(struct imx7_csi *csi) 382{ 383 struct imx_media_video_dev *vdev = csi->vdev; 384 int ret; 385 386 ret = imx_media_alloc_dma_buf(csi->dev, &csi->underrun_buf, 387 vdev->fmt.sizeimage); 388 if (ret < 0) { 389 v4l2_warn(&csi->sd, "consider increasing the CMA area\n"); 390 return ret; 391 } 392 393 csi->frame_sequence = 0; 394 csi->last_eof = false; 395 init_completion(&csi->last_eof_completion); 396 397 imx7_csi_setup_vb2_buf(csi); 398 399 return 0; 400} 401 402static void imx7_csi_dma_cleanup(struct imx7_csi *csi, 403 enum vb2_buffer_state return_status) 404{ 405 imx7_csi_dma_unsetup_vb2_buf(csi, return_status); 406 imx_media_free_dma_buf(csi->dev, &csi->underrun_buf); 407} 408 409static void imx7_csi_dma_stop(struct imx7_csi *csi) 410{ 411 unsigned long timeout_jiffies; 412 unsigned long flags; 413 int ret; 414 415 /* mark next EOF interrupt as the last before stream off */ 416 spin_lock_irqsave(&csi->irqlock, flags); 417 csi->last_eof = true; 418 spin_unlock_irqrestore(&csi->irqlock, flags); 419 420 /* 421 * and then wait for interrupt handler to mark completion. 422 */ 423 timeout_jiffies = msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT); 424 ret = wait_for_completion_timeout(&csi->last_eof_completion, 425 timeout_jiffies); 426 if (ret == 0) 427 v4l2_warn(&csi->sd, "wait last EOF timeout\n"); 428 429 imx7_csi_hw_disable_irq(csi); 430} 431 432static void imx7_csi_configure(struct imx7_csi *csi) 433{ 434 struct imx_media_video_dev *vdev = csi->vdev; 435 struct v4l2_pix_format *out_pix = &vdev->fmt; 436 int width = out_pix->width; 437 u32 stride = 0; 438 u32 cr3 = BIT_FRMCNT_RST; 439 u32 cr1, cr18; 440 441 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18); 442 443 cr18 &= ~(BIT_CSI_HW_ENABLE | BIT_MIPI_DATA_FORMAT_MASK | 444 BIT_DATA_FROM_MIPI | BIT_BASEADDR_CHG_ERR_EN | 445 BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL | 446 BIT_DEINTERLACE_EN); 447 448 if (out_pix->field == V4L2_FIELD_INTERLACED) { 449 cr18 |= BIT_DEINTERLACE_EN; 450 stride = out_pix->width; 451 } 452 453 if (!csi->is_csi2) { 454 cr1 = BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE | BIT_HSYNC_POL 455 | BIT_FCC | BIT_MCLKDIV(1) | BIT_MCLKEN; 456 457 cr18 |= BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL | 458 BIT_BASEADDR_CHG_ERR_EN; 459 460 if (out_pix->pixelformat == V4L2_PIX_FMT_UYVY || 461 out_pix->pixelformat == V4L2_PIX_FMT_YUYV) 462 width *= 2; 463 } else { 464 cr1 = BIT_SOF_POL | BIT_REDGE | BIT_HSYNC_POL | BIT_FCC 465 | BIT_MCLKDIV(1) | BIT_MCLKEN; 466 467 cr18 |= BIT_DATA_FROM_MIPI; 468 469 switch (csi->format_mbus[IMX7_CSI_PAD_SINK].code) { 470 case MEDIA_BUS_FMT_Y8_1X8: 471 case MEDIA_BUS_FMT_SBGGR8_1X8: 472 case MEDIA_BUS_FMT_SGBRG8_1X8: 473 case MEDIA_BUS_FMT_SGRBG8_1X8: 474 case MEDIA_BUS_FMT_SRGGB8_1X8: 475 cr18 |= BIT_MIPI_DATA_FORMAT_RAW8; 476 break; 477 case MEDIA_BUS_FMT_Y10_1X10: 478 case MEDIA_BUS_FMT_SBGGR10_1X10: 479 case MEDIA_BUS_FMT_SGBRG10_1X10: 480 case MEDIA_BUS_FMT_SGRBG10_1X10: 481 case MEDIA_BUS_FMT_SRGGB10_1X10: 482 cr3 |= BIT_TWO_8BIT_SENSOR; 483 cr18 |= BIT_MIPI_DATA_FORMAT_RAW10; 484 break; 485 case MEDIA_BUS_FMT_Y12_1X12: 486 case MEDIA_BUS_FMT_SBGGR12_1X12: 487 case MEDIA_BUS_FMT_SGBRG12_1X12: 488 case MEDIA_BUS_FMT_SGRBG12_1X12: 489 case MEDIA_BUS_FMT_SRGGB12_1X12: 490 cr3 |= BIT_TWO_8BIT_SENSOR; 491 cr18 |= BIT_MIPI_DATA_FORMAT_RAW12; 492 break; 493 case MEDIA_BUS_FMT_Y14_1X14: 494 case MEDIA_BUS_FMT_SBGGR14_1X14: 495 case MEDIA_BUS_FMT_SGBRG14_1X14: 496 case MEDIA_BUS_FMT_SGRBG14_1X14: 497 case MEDIA_BUS_FMT_SRGGB14_1X14: 498 cr3 |= BIT_TWO_8BIT_SENSOR; 499 cr18 |= BIT_MIPI_DATA_FORMAT_RAW14; 500 break; 501 502 /* 503 * The CSI bridge has a 16-bit input bus. Depending on the 504 * connected source, data may be transmitted with 8 or 10 bits 505 * per clock sample (in bits [9:2] or [9:0] respectively) or 506 * with 16 bits per clock sample (in bits [15:0]). The data is 507 * then packed into a 32-bit FIFO (as shown in figure 13-11 of 508 * the i.MX8MM reference manual rev. 3). 509 * 510 * The data packing in a 32-bit FIFO input word is controlled by 511 * the CR3 TWO_8BIT_SENSOR field (also known as SENSOR_16BITS in 512 * the i.MX8MM reference manual). When set to 0, data packing 513 * groups four 8-bit input samples (bits [9:2]). When set to 1, 514 * data packing groups two 16-bit input samples (bits [15:0]). 515 * 516 * The register field CR18 MIPI_DOUBLE_CMPNT also needs to be 517 * configured according to the input format for YUV 4:2:2 data. 518 * The field controls the gasket between the CSI-2 receiver and 519 * the CSI bridge. On i.MX7 and i.MX8MM, the field must be set 520 * to 1 when the CSIS outputs 16-bit samples. On i.MX8MQ, the 521 * gasket ignores the MIPI_DOUBLE_CMPNT bit and YUV 4:2:2 always 522 * uses 16-bit samples. Setting MIPI_DOUBLE_CMPNT in that case 523 * has no effect, but doesn't cause any issue. 524 */ 525 case MEDIA_BUS_FMT_UYVY8_2X8: 526 case MEDIA_BUS_FMT_YUYV8_2X8: 527 cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B; 528 break; 529 case MEDIA_BUS_FMT_UYVY8_1X16: 530 case MEDIA_BUS_FMT_YUYV8_1X16: 531 cr3 |= BIT_TWO_8BIT_SENSOR; 532 cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B | 533 BIT_MIPI_DOUBLE_CMPNT; 534 break; 535 } 536 } 537 538 imx7_csi_reg_write(csi, cr1, CSI_CSICR1); 539 imx7_csi_reg_write(csi, BIT_DMA_BURST_TYPE_RFF_INCR16, CSI_CSICR2); 540 imx7_csi_reg_write(csi, cr3, CSI_CSICR3); 541 imx7_csi_reg_write(csi, cr18, CSI_CSICR18); 542 543 imx7_csi_reg_write(csi, (width * out_pix->height) >> 2, CSI_CSIRXCNT); 544 imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(width) | 545 BIT_IMAGE_HEIGHT(out_pix->height), 546 CSI_CSIIMAG_PARA); 547 imx7_csi_reg_write(csi, stride, CSI_CSIFBUF_PARA); 548} 549 550static int imx7_csi_init(struct imx7_csi *csi) 551{ 552 int ret; 553 554 ret = clk_prepare_enable(csi->mclk); 555 if (ret < 0) 556 return ret; 557 558 imx7_csi_configure(csi); 559 560 ret = imx7_csi_dma_setup(csi); 561 if (ret < 0) 562 return ret; 563 564 return 0; 565} 566 567static void imx7_csi_deinit(struct imx7_csi *csi, 568 enum vb2_buffer_state return_status) 569{ 570 imx7_csi_dma_cleanup(csi, return_status); 571 imx7_csi_init_default(csi); 572 imx7_csi_dmareq_rff_disable(csi); 573 clk_disable_unprepare(csi->mclk); 574} 575 576static void imx7_csi_baseaddr_switch_on_second_frame(struct imx7_csi *csi) 577{ 578 u32 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18); 579 580 cr18 |= BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL | 581 BIT_BASEADDR_CHG_ERR_EN; 582 cr18 |= BIT_MASK_OPTION_SECOND_FRAME; 583 imx7_csi_reg_write(csi, cr18, CSI_CSICR18); 584} 585 586static void imx7_csi_enable(struct imx7_csi *csi) 587{ 588 /* Clear the Rx FIFO and reflash the DMA controller. */ 589 imx7_csi_rx_fifo_clear(csi); 590 imx7_csi_dma_reflash(csi); 591 592 usleep_range(2000, 3000); 593 594 /* Clear and enable the interrupts. */ 595 imx7_csi_irq_clear(csi); 596 imx7_csi_hw_enable_irq(csi); 597 598 /* Enable the RxFIFO DMA and the CSI. */ 599 imx7_csi_dmareq_rff_enable(csi); 600 imx7_csi_hw_enable(csi); 601 602 if (csi->model == IMX7_CSI_IMX8MQ) 603 imx7_csi_baseaddr_switch_on_second_frame(csi); 604} 605 606static void imx7_csi_disable(struct imx7_csi *csi) 607{ 608 imx7_csi_dma_stop(csi); 609 610 imx7_csi_dmareq_rff_disable(csi); 611 612 imx7_csi_hw_disable_irq(csi); 613 614 imx7_csi_hw_disable(csi); 615} 616 617/* ----------------------------------------------------------------------------- 618 * Interrupt Handling 619 */ 620 621static void imx7_csi_error_recovery(struct imx7_csi *csi) 622{ 623 imx7_csi_hw_disable(csi); 624 625 imx7_csi_rx_fifo_clear(csi); 626 627 imx7_csi_dma_reflash(csi); 628 629 imx7_csi_hw_enable(csi); 630} 631 632static void imx7_csi_vb2_buf_done(struct imx7_csi *csi) 633{ 634 struct imx_media_video_dev *vdev = csi->vdev; 635 struct imx_media_buffer *done, *next; 636 struct vb2_buffer *vb; 637 dma_addr_t phys; 638 639 done = csi->active_vb2_buf[csi->buf_num]; 640 if (done) { 641 done->vbuf.field = vdev->fmt.field; 642 done->vbuf.sequence = csi->frame_sequence; 643 vb = &done->vbuf.vb2_buf; 644 vb->timestamp = ktime_get_ns(); 645 vb2_buffer_done(vb, VB2_BUF_STATE_DONE); 646 } 647 csi->frame_sequence++; 648 649 /* get next queued buffer */ 650 next = imx_media_capture_device_next_buf(vdev); 651 if (next) { 652 phys = vb2_dma_contig_plane_dma_addr(&next->vbuf.vb2_buf, 0); 653 csi->active_vb2_buf[csi->buf_num] = next; 654 } else { 655 phys = csi->underrun_buf.phys; 656 csi->active_vb2_buf[csi->buf_num] = NULL; 657 } 658 659 imx7_csi_update_buf(csi, phys, csi->buf_num); 660} 661 662static irqreturn_t imx7_csi_irq_handler(int irq, void *data) 663{ 664 struct imx7_csi *csi = data; 665 u32 status; 666 667 spin_lock(&csi->irqlock); 668 669 status = imx7_csi_irq_clear(csi); 670 671 if (status & BIT_RFF_OR_INT) { 672 dev_warn(csi->dev, "Rx fifo overflow\n"); 673 imx7_csi_error_recovery(csi); 674 } 675 676 if (status & BIT_HRESP_ERR_INT) { 677 dev_warn(csi->dev, "Hresponse error detected\n"); 678 imx7_csi_error_recovery(csi); 679 } 680 681 if (status & BIT_ADDR_CH_ERR_INT) { 682 imx7_csi_hw_disable(csi); 683 684 imx7_csi_dma_reflash(csi); 685 686 imx7_csi_hw_enable(csi); 687 } 688 689 if ((status & BIT_DMA_TSF_DONE_FB1) && 690 (status & BIT_DMA_TSF_DONE_FB2)) { 691 /* 692 * For both FB1 and FB2 interrupter bits set case, 693 * CSI DMA is work in one of FB1 and FB2 buffer, 694 * but software can not know the state. 695 * Skip it to avoid base address updated 696 * when csi work in field0 and field1 will write to 697 * new base address. 698 */ 699 } else if (status & BIT_DMA_TSF_DONE_FB1) { 700 csi->buf_num = 0; 701 } else if (status & BIT_DMA_TSF_DONE_FB2) { 702 csi->buf_num = 1; 703 } 704 705 if ((status & BIT_DMA_TSF_DONE_FB1) || 706 (status & BIT_DMA_TSF_DONE_FB2)) { 707 imx7_csi_vb2_buf_done(csi); 708 709 if (csi->last_eof) { 710 complete(&csi->last_eof_completion); 711 csi->last_eof = false; 712 } 713 } 714 715 spin_unlock(&csi->irqlock); 716 717 return IRQ_HANDLED; 718} 719 720/* ----------------------------------------------------------------------------- 721 * V4L2 Subdev Operations 722 */ 723 724static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable) 725{ 726 struct imx7_csi *csi = v4l2_get_subdevdata(sd); 727 int ret = 0; 728 729 mutex_lock(&csi->lock); 730 731 if (!csi->src_sd) { 732 ret = -EPIPE; 733 goto out_unlock; 734 } 735 736 if (csi->is_streaming == !!enable) 737 goto out_unlock; 738 739 if (enable) { 740 ret = imx7_csi_init(csi); 741 if (ret < 0) 742 goto out_unlock; 743 744 ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1); 745 if (ret < 0) { 746 imx7_csi_deinit(csi, VB2_BUF_STATE_QUEUED); 747 goto out_unlock; 748 } 749 750 imx7_csi_enable(csi); 751 } else { 752 imx7_csi_disable(csi); 753 754 v4l2_subdev_call(csi->src_sd, video, s_stream, 0); 755 756 imx7_csi_deinit(csi, VB2_BUF_STATE_ERROR); 757 } 758 759 csi->is_streaming = !!enable; 760 761out_unlock: 762 mutex_unlock(&csi->lock); 763 764 return ret; 765} 766 767static int imx7_csi_init_cfg(struct v4l2_subdev *sd, 768 struct v4l2_subdev_state *sd_state) 769{ 770 struct imx7_csi *csi = v4l2_get_subdevdata(sd); 771 struct v4l2_mbus_framefmt *mf; 772 int ret; 773 int i; 774 775 for (i = 0; i < IMX7_CSI_PADS_NUM; i++) { 776 mf = v4l2_subdev_get_try_format(sd, sd_state, i); 777 778 ret = imx_media_init_mbus_fmt(mf, 800, 600, 0, V4L2_FIELD_NONE, 779 &csi->cc[i]); 780 if (ret < 0) 781 return ret; 782 } 783 784 return 0; 785} 786 787static struct v4l2_mbus_framefmt * 788imx7_csi_get_format(struct imx7_csi *csi, 789 struct v4l2_subdev_state *sd_state, 790 unsigned int pad, 791 enum v4l2_subdev_format_whence which) 792{ 793 if (which == V4L2_SUBDEV_FORMAT_TRY) 794 return v4l2_subdev_get_try_format(&csi->sd, sd_state, pad); 795 796 return &csi->format_mbus[pad]; 797} 798 799static int imx7_csi_enum_mbus_code(struct v4l2_subdev *sd, 800 struct v4l2_subdev_state *sd_state, 801 struct v4l2_subdev_mbus_code_enum *code) 802{ 803 struct imx7_csi *csi = v4l2_get_subdevdata(sd); 804 struct v4l2_mbus_framefmt *in_fmt; 805 int ret = 0; 806 807 mutex_lock(&csi->lock); 808 809 in_fmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SINK, 810 code->which); 811 812 switch (code->pad) { 813 case IMX7_CSI_PAD_SINK: 814 ret = imx_media_enum_mbus_formats(&code->code, code->index, 815 PIXFMT_SEL_ANY); 816 break; 817 case IMX7_CSI_PAD_SRC: 818 if (code->index != 0) { 819 ret = -EINVAL; 820 goto out_unlock; 821 } 822 823 code->code = in_fmt->code; 824 break; 825 default: 826 ret = -EINVAL; 827 } 828 829out_unlock: 830 mutex_unlock(&csi->lock); 831 832 return ret; 833} 834 835static int imx7_csi_get_fmt(struct v4l2_subdev *sd, 836 struct v4l2_subdev_state *sd_state, 837 struct v4l2_subdev_format *sdformat) 838{ 839 struct imx7_csi *csi = v4l2_get_subdevdata(sd); 840 struct v4l2_mbus_framefmt *fmt; 841 int ret = 0; 842 843 mutex_lock(&csi->lock); 844 845 fmt = imx7_csi_get_format(csi, sd_state, sdformat->pad, 846 sdformat->which); 847 if (!fmt) { 848 ret = -EINVAL; 849 goto out_unlock; 850 } 851 852 sdformat->format = *fmt; 853 854out_unlock: 855 mutex_unlock(&csi->lock); 856 857 return ret; 858} 859 860static int imx7_csi_try_fmt(struct imx7_csi *csi, 861 struct v4l2_subdev_state *sd_state, 862 struct v4l2_subdev_format *sdformat, 863 const struct imx_media_pixfmt **cc) 864{ 865 const struct imx_media_pixfmt *in_cc; 866 struct v4l2_mbus_framefmt *in_fmt; 867 u32 code; 868 869 in_fmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SINK, 870 sdformat->which); 871 if (!in_fmt) 872 return -EINVAL; 873 874 switch (sdformat->pad) { 875 case IMX7_CSI_PAD_SRC: 876 in_cc = imx_media_find_mbus_format(in_fmt->code, 877 PIXFMT_SEL_ANY); 878 879 sdformat->format.width = in_fmt->width; 880 sdformat->format.height = in_fmt->height; 881 sdformat->format.code = in_fmt->code; 882 sdformat->format.field = in_fmt->field; 883 *cc = in_cc; 884 885 sdformat->format.colorspace = in_fmt->colorspace; 886 sdformat->format.xfer_func = in_fmt->xfer_func; 887 sdformat->format.quantization = in_fmt->quantization; 888 sdformat->format.ycbcr_enc = in_fmt->ycbcr_enc; 889 break; 890 case IMX7_CSI_PAD_SINK: 891 *cc = imx_media_find_mbus_format(sdformat->format.code, 892 PIXFMT_SEL_ANY); 893 if (!*cc) { 894 imx_media_enum_mbus_formats(&code, 0, 895 PIXFMT_SEL_YUV_RGB); 896 *cc = imx_media_find_mbus_format(code, 897 PIXFMT_SEL_YUV_RGB); 898 sdformat->format.code = (*cc)->codes[0]; 899 } 900 901 if (sdformat->format.field != V4L2_FIELD_INTERLACED) 902 sdformat->format.field = V4L2_FIELD_NONE; 903 break; 904 default: 905 return -EINVAL; 906 } 907 908 imx_media_try_colorimetry(&sdformat->format, false); 909 910 return 0; 911} 912 913static int imx7_csi_set_fmt(struct v4l2_subdev *sd, 914 struct v4l2_subdev_state *sd_state, 915 struct v4l2_subdev_format *sdformat) 916{ 917 struct imx7_csi *csi = v4l2_get_subdevdata(sd); 918 const struct imx_media_pixfmt *outcc; 919 struct v4l2_mbus_framefmt *outfmt; 920 const struct imx_media_pixfmt *cc; 921 struct v4l2_mbus_framefmt *fmt; 922 struct v4l2_subdev_format format; 923 int ret = 0; 924 925 if (sdformat->pad >= IMX7_CSI_PADS_NUM) 926 return -EINVAL; 927 928 mutex_lock(&csi->lock); 929 930 if (csi->is_streaming) { 931 ret = -EBUSY; 932 goto out_unlock; 933 } 934 935 ret = imx7_csi_try_fmt(csi, sd_state, sdformat, &cc); 936 if (ret < 0) 937 goto out_unlock; 938 939 fmt = imx7_csi_get_format(csi, sd_state, sdformat->pad, 940 sdformat->which); 941 if (!fmt) { 942 ret = -EINVAL; 943 goto out_unlock; 944 } 945 946 *fmt = sdformat->format; 947 948 if (sdformat->pad == IMX7_CSI_PAD_SINK) { 949 /* propagate format to source pads */ 950 format.pad = IMX7_CSI_PAD_SRC; 951 format.which = sdformat->which; 952 format.format = sdformat->format; 953 if (imx7_csi_try_fmt(csi, sd_state, &format, &outcc)) { 954 ret = -EINVAL; 955 goto out_unlock; 956 } 957 outfmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SRC, 958 sdformat->which); 959 *outfmt = format.format; 960 961 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) 962 csi->cc[IMX7_CSI_PAD_SRC] = outcc; 963 } 964 965 if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE) 966 csi->cc[sdformat->pad] = cc; 967 968out_unlock: 969 mutex_unlock(&csi->lock); 970 971 return ret; 972} 973 974static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd, 975 struct media_link *link, 976 struct v4l2_subdev_format *source_fmt, 977 struct v4l2_subdev_format *sink_fmt) 978{ 979 struct imx7_csi *csi = v4l2_get_subdevdata(sd); 980 struct imx_media_video_dev *vdev = csi->vdev; 981 const struct v4l2_pix_format *out_pix = &vdev->fmt; 982 struct media_pad *pad; 983 int ret; 984 985 if (!csi->src_sd) 986 return -EPIPE; 987 988 /* 989 * Validate the source link, and record whether the source uses the 990 * parallel input or the CSI-2 receiver. 991 */ 992 ret = v4l2_subdev_link_validate_default(sd, link, source_fmt, sink_fmt); 993 if (ret) 994 return ret; 995 996 switch (csi->src_sd->entity.function) { 997 case MEDIA_ENT_F_VID_IF_BRIDGE: 998 /* The input is the CSI-2 receiver. */ 999 csi->is_csi2 = true; 1000 break; 1001 1002 case MEDIA_ENT_F_VID_MUX: 1003 /* The input is the mux, check its input. */ 1004 pad = imx_media_pipeline_pad(&csi->src_sd->entity, 0, 0, true); 1005 if (!pad) 1006 return -ENODEV; 1007 1008 csi->is_csi2 = pad->entity->function == MEDIA_ENT_F_VID_IF_BRIDGE; 1009 break; 1010 1011 default: 1012 /* 1013 * The input is an external entity, it must use the parallel 1014 * bus. 1015 */ 1016 csi->is_csi2 = false; 1017 break; 1018 } 1019 1020 /* Validate the sink link, ensure the pixel format is supported. */ 1021 switch (out_pix->pixelformat) { 1022 case V4L2_PIX_FMT_UYVY: 1023 case V4L2_PIX_FMT_YUYV: 1024 case V4L2_PIX_FMT_GREY: 1025 case V4L2_PIX_FMT_Y10: 1026 case V4L2_PIX_FMT_Y12: 1027 case V4L2_PIX_FMT_SBGGR8: 1028 case V4L2_PIX_FMT_SGBRG8: 1029 case V4L2_PIX_FMT_SGRBG8: 1030 case V4L2_PIX_FMT_SRGGB8: 1031 case V4L2_PIX_FMT_SBGGR16: 1032 case V4L2_PIX_FMT_SGBRG16: 1033 case V4L2_PIX_FMT_SGRBG16: 1034 case V4L2_PIX_FMT_SRGGB16: 1035 break; 1036 1037 default: 1038 dev_dbg(csi->dev, "Invalid capture pixel format 0x%08x\n", 1039 out_pix->pixelformat); 1040 return -EINVAL; 1041 } 1042 1043 return 0; 1044} 1045 1046static int imx7_csi_registered(struct v4l2_subdev *sd) 1047{ 1048 struct imx7_csi *csi = v4l2_get_subdevdata(sd); 1049 int ret; 1050 int i; 1051 1052 for (i = 0; i < IMX7_CSI_PADS_NUM; i++) { 1053 /* set a default mbus format */ 1054 ret = imx_media_init_mbus_fmt(&csi->format_mbus[i], 1055 800, 600, 0, V4L2_FIELD_NONE, 1056 &csi->cc[i]); 1057 if (ret < 0) 1058 return ret; 1059 1060 /* init default frame interval */ 1061 csi->frame_interval[i].numerator = 1; 1062 csi->frame_interval[i].denominator = 30; 1063 } 1064 1065 csi->vdev = imx_media_capture_device_init(csi->sd.dev, &csi->sd, 1066 IMX7_CSI_PAD_SRC, false); 1067 if (IS_ERR(csi->vdev)) 1068 return PTR_ERR(csi->vdev); 1069 1070 ret = imx_media_capture_device_register(csi->vdev, 1071 MEDIA_LNK_FL_IMMUTABLE); 1072 if (ret) 1073 imx_media_capture_device_remove(csi->vdev); 1074 1075 return ret; 1076} 1077 1078static void imx7_csi_unregistered(struct v4l2_subdev *sd) 1079{ 1080 struct imx7_csi *csi = v4l2_get_subdevdata(sd); 1081 1082 imx_media_capture_device_unregister(csi->vdev); 1083 imx_media_capture_device_remove(csi->vdev); 1084} 1085 1086static const struct v4l2_subdev_video_ops imx7_csi_video_ops = { 1087 .s_stream = imx7_csi_s_stream, 1088}; 1089 1090static const struct v4l2_subdev_pad_ops imx7_csi_pad_ops = { 1091 .init_cfg = imx7_csi_init_cfg, 1092 .enum_mbus_code = imx7_csi_enum_mbus_code, 1093 .get_fmt = imx7_csi_get_fmt, 1094 .set_fmt = imx7_csi_set_fmt, 1095 .link_validate = imx7_csi_pad_link_validate, 1096}; 1097 1098static const struct v4l2_subdev_ops imx7_csi_subdev_ops = { 1099 .video = &imx7_csi_video_ops, 1100 .pad = &imx7_csi_pad_ops, 1101}; 1102 1103static const struct v4l2_subdev_internal_ops imx7_csi_internal_ops = { 1104 .registered = imx7_csi_registered, 1105 .unregistered = imx7_csi_unregistered, 1106}; 1107 1108/* ----------------------------------------------------------------------------- 1109 * Media Entity Operations 1110 */ 1111 1112static const struct media_entity_operations imx7_csi_entity_ops = { 1113 .link_validate = v4l2_subdev_link_validate, 1114 .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1, 1115}; 1116 1117/* ----------------------------------------------------------------------------- 1118 * Probe & Remove 1119 */ 1120 1121static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier, 1122 struct v4l2_subdev *sd, 1123 struct v4l2_async_subdev *asd) 1124{ 1125 struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier); 1126 struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK]; 1127 1128 /* 1129 * If the subdev is a video mux, it must be one of the CSI 1130 * muxes. Mark it as such via its group id. 1131 */ 1132 if (sd->entity.function == MEDIA_ENT_F_VID_MUX) 1133 sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX; 1134 1135 csi->src_sd = sd; 1136 1137 return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED | 1138 MEDIA_LNK_FL_IMMUTABLE); 1139} 1140 1141static const struct v4l2_async_notifier_operations imx7_csi_notify_ops = { 1142 .bound = imx7_csi_notify_bound, 1143}; 1144 1145static int imx7_csi_async_register(struct imx7_csi *csi) 1146{ 1147 struct v4l2_async_subdev *asd; 1148 struct fwnode_handle *ep; 1149 int ret; 1150 1151 v4l2_async_nf_init(&csi->notifier); 1152 1153 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0, 1154 FWNODE_GRAPH_ENDPOINT_NEXT); 1155 if (ep) { 1156 asd = v4l2_async_nf_add_fwnode_remote(&csi->notifier, ep, 1157 struct v4l2_async_subdev); 1158 1159 fwnode_handle_put(ep); 1160 1161 if (IS_ERR(asd)) { 1162 ret = PTR_ERR(asd); 1163 /* OK if asd already exists */ 1164 if (ret != -EEXIST) 1165 return ret; 1166 } 1167 } 1168 1169 csi->notifier.ops = &imx7_csi_notify_ops; 1170 1171 ret = v4l2_async_subdev_nf_register(&csi->sd, &csi->notifier); 1172 if (ret) 1173 return ret; 1174 1175 return v4l2_async_register_subdev(&csi->sd); 1176} 1177 1178static int imx7_csi_probe(struct platform_device *pdev) 1179{ 1180 struct device *dev = &pdev->dev; 1181 struct device_node *node = dev->of_node; 1182 struct imx_media_dev *imxmd; 1183 struct imx7_csi *csi; 1184 int i, ret; 1185 1186 csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL); 1187 if (!csi) 1188 return -ENOMEM; 1189 1190 csi->dev = dev; 1191 1192 csi->mclk = devm_clk_get(&pdev->dev, "mclk"); 1193 if (IS_ERR(csi->mclk)) { 1194 ret = PTR_ERR(csi->mclk); 1195 dev_err(dev, "Failed to get mclk: %d", ret); 1196 return ret; 1197 } 1198 1199 csi->irq = platform_get_irq(pdev, 0); 1200 if (csi->irq < 0) 1201 return csi->irq; 1202 1203 csi->regbase = devm_platform_ioremap_resource(pdev, 0); 1204 if (IS_ERR(csi->regbase)) 1205 return PTR_ERR(csi->regbase); 1206 1207 csi->model = (enum imx_csi_model)(uintptr_t)of_device_get_match_data(&pdev->dev); 1208 1209 spin_lock_init(&csi->irqlock); 1210 mutex_init(&csi->lock); 1211 1212 /* install interrupt handler */ 1213 ret = devm_request_irq(dev, csi->irq, imx7_csi_irq_handler, 0, "csi", 1214 (void *)csi); 1215 if (ret < 0) { 1216 dev_err(dev, "Request CSI IRQ failed.\n"); 1217 goto destroy_mutex; 1218 } 1219 1220 /* add media device */ 1221 imxmd = imx_media_dev_init(dev, NULL); 1222 if (IS_ERR(imxmd)) { 1223 ret = PTR_ERR(imxmd); 1224 goto destroy_mutex; 1225 } 1226 platform_set_drvdata(pdev, &csi->sd); 1227 1228 ret = imx_media_of_add_csi(imxmd, node); 1229 if (ret < 0 && ret != -ENODEV && ret != -EEXIST) 1230 goto cleanup; 1231 1232 ret = imx_media_dev_notifier_register(imxmd, NULL); 1233 if (ret < 0) 1234 goto cleanup; 1235 1236 csi->imxmd = imxmd; 1237 v4l2_subdev_init(&csi->sd, &imx7_csi_subdev_ops); 1238 v4l2_set_subdevdata(&csi->sd, csi); 1239 csi->sd.internal_ops = &imx7_csi_internal_ops; 1240 csi->sd.entity.ops = &imx7_csi_entity_ops; 1241 csi->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; 1242 csi->sd.dev = &pdev->dev; 1243 csi->sd.owner = THIS_MODULE; 1244 csi->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; 1245 csi->sd.grp_id = IMX_MEDIA_GRP_ID_CSI; 1246 snprintf(csi->sd.name, sizeof(csi->sd.name), "csi"); 1247 1248 for (i = 0; i < IMX7_CSI_PADS_NUM; i++) 1249 csi->pad[i].flags = (i == IMX7_CSI_PAD_SINK) ? 1250 MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; 1251 1252 ret = media_entity_pads_init(&csi->sd.entity, IMX7_CSI_PADS_NUM, 1253 csi->pad); 1254 if (ret < 0) 1255 goto cleanup; 1256 1257 ret = imx7_csi_async_register(csi); 1258 if (ret) 1259 goto subdev_notifier_cleanup; 1260 1261 return 0; 1262 1263subdev_notifier_cleanup: 1264 v4l2_async_nf_unregister(&csi->notifier); 1265 v4l2_async_nf_cleanup(&csi->notifier); 1266 1267cleanup: 1268 v4l2_async_nf_unregister(&imxmd->notifier); 1269 v4l2_async_nf_cleanup(&imxmd->notifier); 1270 v4l2_device_unregister(&imxmd->v4l2_dev); 1271 media_device_unregister(&imxmd->md); 1272 media_device_cleanup(&imxmd->md); 1273 1274destroy_mutex: 1275 mutex_destroy(&csi->lock); 1276 1277 return ret; 1278} 1279 1280static int imx7_csi_remove(struct platform_device *pdev) 1281{ 1282 struct v4l2_subdev *sd = platform_get_drvdata(pdev); 1283 struct imx7_csi *csi = v4l2_get_subdevdata(sd); 1284 struct imx_media_dev *imxmd = csi->imxmd; 1285 1286 v4l2_async_nf_unregister(&imxmd->notifier); 1287 v4l2_async_nf_cleanup(&imxmd->notifier); 1288 1289 media_device_unregister(&imxmd->md); 1290 v4l2_device_unregister(&imxmd->v4l2_dev); 1291 media_device_cleanup(&imxmd->md); 1292 1293 v4l2_async_nf_unregister(&csi->notifier); 1294 v4l2_async_nf_cleanup(&csi->notifier); 1295 v4l2_async_unregister_subdev(sd); 1296 1297 mutex_destroy(&csi->lock); 1298 1299 return 0; 1300} 1301 1302static const struct of_device_id imx7_csi_of_match[] = { 1303 { .compatible = "fsl,imx8mq-csi", .data = (void *)IMX7_CSI_IMX8MQ }, 1304 { .compatible = "fsl,imx7-csi", .data = (void *)IMX7_CSI_IMX7 }, 1305 { .compatible = "fsl,imx6ul-csi", .data = (void *)IMX7_CSI_IMX7 }, 1306 { }, 1307}; 1308MODULE_DEVICE_TABLE(of, imx7_csi_of_match); 1309 1310static struct platform_driver imx7_csi_driver = { 1311 .probe = imx7_csi_probe, 1312 .remove = imx7_csi_remove, 1313 .driver = { 1314 .of_match_table = imx7_csi_of_match, 1315 .name = "imx7-csi", 1316 }, 1317}; 1318module_platform_driver(imx7_csi_driver); 1319 1320MODULE_DESCRIPTION("i.MX7 CSI subdev driver"); 1321MODULE_AUTHOR("Rui Miguel Silva <rui.silva@linaro.org>"); 1322MODULE_LICENSE("GPL v2"); 1323MODULE_ALIAS("platform:imx7-csi");