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

[media] atmel-isc: add the Image Sensor Controller code

Add driver for the Image Sensor Controller. It manages
incoming data from a parallel based CMOS/CCD sensor.
It has an internal image processor, also integrates a
triple channel direct memory access controller master
interface.

Signed-off-by: Songjun Wu <songjun.wu@microchip.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

authored by

Songjun Wu and committed by
Mauro Carvalho Chehab
10626744 8d4b231a

+1692
+1
drivers/media/platform/Kconfig
··· 111 111 source "drivers/media/platform/am437x/Kconfig" 112 112 source "drivers/media/platform/xilinx/Kconfig" 113 113 source "drivers/media/platform/rcar-vin/Kconfig" 114 + source "drivers/media/platform/atmel/Kconfig" 114 115 115 116 config VIDEO_TI_CAL 116 117 tristate "TI CAL (Camera Adaptation Layer) driver"
+2
drivers/media/platform/Makefile
··· 58 58 59 59 obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin/ 60 60 61 + obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel/ 62 + 61 63 ccflags-y += -I$(srctree)/drivers/media/i2c 62 64 63 65 obj-$(CONFIG_VIDEO_MEDIATEK_VPU) += mtk-vpu/
+9
drivers/media/platform/atmel/Kconfig
··· 1 + config VIDEO_ATMEL_ISC 2 + tristate "ATMEL Image Sensor Controller (ISC) support" 3 + depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API && HAS_DMA 4 + depends on ARCH_AT91 || COMPILE_TEST 5 + select VIDEOBUF2_DMA_CONTIG 6 + select REGMAP_MMIO 7 + help 8 + This module makes the ATMEL Image Sensor Controller available 9 + as a v4l2 device.
+1
drivers/media/platform/atmel/Makefile
··· 1 + obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel-isc.o
+165
drivers/media/platform/atmel/atmel-isc-regs.h
··· 1 + #ifndef __ATMEL_ISC_REGS_H 2 + #define __ATMEL_ISC_REGS_H 3 + 4 + #include <linux/bitops.h> 5 + 6 + /* ISC Control Enable Register 0 */ 7 + #define ISC_CTRLEN 0x00000000 8 + 9 + /* ISC Control Disable Register 0 */ 10 + #define ISC_CTRLDIS 0x00000004 11 + 12 + /* ISC Control Status Register 0 */ 13 + #define ISC_CTRLSR 0x00000008 14 + 15 + #define ISC_CTRL_CAPTURE BIT(0) 16 + #define ISC_CTRL_UPPRO BIT(1) 17 + #define ISC_CTRL_HISREQ BIT(2) 18 + #define ISC_CTRL_HISCLR BIT(3) 19 + 20 + /* ISC Parallel Front End Configuration 0 Register */ 21 + #define ISC_PFE_CFG0 0x0000000c 22 + 23 + #define ISC_PFE_CFG0_HPOL_LOW BIT(0) 24 + #define ISC_PFE_CFG0_VPOL_LOW BIT(1) 25 + #define ISC_PFE_CFG0_PPOL_LOW BIT(2) 26 + 27 + #define ISC_PFE_CFG0_MODE_PROGRESSIVE (0x0 << 4) 28 + #define ISC_PFE_CFG0_MODE_MASK GENMASK(6, 4) 29 + 30 + #define ISC_PFE_CFG0_BPS_EIGHT (0x4 << 28) 31 + #define ISC_PFG_CFG0_BPS_NINE (0x3 << 28) 32 + #define ISC_PFG_CFG0_BPS_TEN (0x2 << 28) 33 + #define ISC_PFG_CFG0_BPS_ELEVEN (0x1 << 28) 34 + #define ISC_PFG_CFG0_BPS_TWELVE (0x0 << 28) 35 + #define ISC_PFE_CFG0_BPS_MASK GENMASK(30, 28) 36 + 37 + /* ISC Clock Enable Register */ 38 + #define ISC_CLKEN 0x00000018 39 + 40 + /* ISC Clock Disable Register */ 41 + #define ISC_CLKDIS 0x0000001c 42 + 43 + /* ISC Clock Status Register */ 44 + #define ISC_CLKSR 0x00000020 45 + 46 + #define ISC_CLK(n) BIT(n) 47 + 48 + /* ISC Clock Configuration Register */ 49 + #define ISC_CLKCFG 0x00000024 50 + #define ISC_CLKCFG_DIV_SHIFT(n) ((n)*16) 51 + #define ISC_CLKCFG_DIV_MASK(n) GENMASK(((n)*16 + 7), (n)*16) 52 + #define ISC_CLKCFG_SEL_SHIFT(n) ((n)*16 + 8) 53 + #define ISC_CLKCFG_SEL_MASK(n) GENMASK(((n)*17 + 8), ((n)*16 + 8)) 54 + 55 + /* ISC Interrupt Enable Register */ 56 + #define ISC_INTEN 0x00000028 57 + 58 + /* ISC Interrupt Disable Register */ 59 + #define ISC_INTDIS 0x0000002c 60 + 61 + /* ISC Interrupt Mask Register */ 62 + #define ISC_INTMASK 0x00000030 63 + 64 + /* ISC Interrupt Status Register */ 65 + #define ISC_INTSR 0x00000034 66 + 67 + #define ISC_INT_DDONE BIT(8) 68 + 69 + /* ISC White Balance Control Register */ 70 + #define ISC_WB_CTRL 0x00000058 71 + 72 + /* ISC White Balance Configuration Register */ 73 + #define ISC_WB_CFG 0x0000005c 74 + 75 + /* ISC Color Filter Array Control Register */ 76 + #define ISC_CFA_CTRL 0x00000070 77 + 78 + /* ISC Color Filter Array Configuration Register */ 79 + #define ISC_CFA_CFG 0x00000074 80 + 81 + #define ISC_BAY_CFG_GRGR 0x0 82 + #define ISC_BAY_CFG_RGRG 0x1 83 + #define ISC_BAY_CFG_GBGB 0x2 84 + #define ISC_BAY_CFG_BGBG 0x3 85 + #define ISC_BAY_CFG_MASK GENMASK(1, 0) 86 + 87 + /* ISC Color Correction Control Register */ 88 + #define ISC_CC_CTRL 0x00000078 89 + 90 + /* ISC Gamma Correction Control Register */ 91 + #define ISC_GAM_CTRL 0x00000094 92 + 93 + /* Color Space Conversion Control Register */ 94 + #define ISC_CSC_CTRL 0x00000398 95 + 96 + /* Contrast And Brightness Control Register */ 97 + #define ISC_CBC_CTRL 0x000003b4 98 + 99 + /* Subsampling 4:4:4 to 4:2:2 Control Register */ 100 + #define ISC_SUB422_CTRL 0x000003c4 101 + 102 + /* Subsampling 4:2:2 to 4:2:0 Control Register */ 103 + #define ISC_SUB420_CTRL 0x000003cc 104 + 105 + /* Rounding, Limiting and Packing Configuration Register */ 106 + #define ISC_RLP_CFG 0x000003d0 107 + 108 + #define ISC_RLP_CFG_MODE_DAT8 0x0 109 + #define ISC_RLP_CFG_MODE_DAT9 0x1 110 + #define ISC_RLP_CFG_MODE_DAT10 0x2 111 + #define ISC_RLP_CFG_MODE_DAT11 0x3 112 + #define ISC_RLP_CFG_MODE_DAT12 0x4 113 + #define ISC_RLP_CFG_MODE_DATY8 0x5 114 + #define ISC_RLP_CFG_MODE_DATY10 0x6 115 + #define ISC_RLP_CFG_MODE_ARGB444 0x7 116 + #define ISC_RLP_CFG_MODE_ARGB555 0x8 117 + #define ISC_RLP_CFG_MODE_RGB565 0x9 118 + #define ISC_RLP_CFG_MODE_ARGB32 0xa 119 + #define ISC_RLP_CFG_MODE_YYCC 0xb 120 + #define ISC_RLP_CFG_MODE_YYCC_LIMITED 0xc 121 + #define ISC_RLP_CFG_MODE_MASK GENMASK(3, 0) 122 + 123 + /* DMA Configuration Register */ 124 + #define ISC_DCFG 0x000003e0 125 + #define ISC_DCFG_IMODE_PACKED8 0x0 126 + #define ISC_DCFG_IMODE_PACKED16 0x1 127 + #define ISC_DCFG_IMODE_PACKED32 0x2 128 + #define ISC_DCFG_IMODE_YC422SP 0x3 129 + #define ISC_DCFG_IMODE_YC422P 0x4 130 + #define ISC_DCFG_IMODE_YC420SP 0x5 131 + #define ISC_DCFG_IMODE_YC420P 0x6 132 + #define ISC_DCFG_IMODE_MASK GENMASK(2, 0) 133 + 134 + #define ISC_DCFG_YMBSIZE_SINGLE (0x0 << 4) 135 + #define ISC_DCFG_YMBSIZE_BEATS4 (0x1 << 4) 136 + #define ISC_DCFG_YMBSIZE_BEATS8 (0x2 << 4) 137 + #define ISC_DCFG_YMBSIZE_BEATS16 (0x3 << 4) 138 + #define ISC_DCFG_YMBSIZE_MASK GENMASK(5, 4) 139 + 140 + #define ISC_DCFG_CMBSIZE_SINGLE (0x0 << 8) 141 + #define ISC_DCFG_CMBSIZE_BEATS4 (0x1 << 8) 142 + #define ISC_DCFG_CMBSIZE_BEATS8 (0x2 << 8) 143 + #define ISC_DCFG_CMBSIZE_BEATS16 (0x3 << 8) 144 + #define ISC_DCFG_CMBSIZE_MASK GENMASK(9, 8) 145 + 146 + /* DMA Control Register */ 147 + #define ISC_DCTRL 0x000003e4 148 + 149 + #define ISC_DCTRL_DVIEW_PACKED (0x0 << 1) 150 + #define ISC_DCTRL_DVIEW_SEMIPLANAR (0x1 << 1) 151 + #define ISC_DCTRL_DVIEW_PLANAR (0x2 << 1) 152 + #define ISC_DCTRL_DVIEW_MASK GENMASK(2, 1) 153 + 154 + #define ISC_DCTRL_IE_IS (0x0 << 4) 155 + 156 + /* DMA Descriptor Address Register */ 157 + #define ISC_DNDA 0x000003e8 158 + 159 + /* DMA Address 0 Register */ 160 + #define ISC_DAD0 0x000003ec 161 + 162 + /* DMA Stride 0 Register */ 163 + #define ISC_DST0 0x000003f0 164 + 165 + #endif
+1514
drivers/media/platform/atmel/atmel-isc.c
··· 1 + /* 2 + * Atmel Image Sensor Controller (ISC) driver 3 + * 4 + * Copyright (C) 2016 Atmel 5 + * 6 + * Author: Songjun Wu <songjun.wu@microchip.com> 7 + * 8 + * This program is free software; you may redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; version 2 of the License. 11 + * 12 + * Sensor-->PFE-->WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB-->RLP-->DMA 13 + * 14 + * ISC video pipeline integrates the following submodules: 15 + * PFE: Parallel Front End to sample the camera sensor input stream 16 + * WB: Programmable white balance in the Bayer domain 17 + * CFA: Color filter array interpolation module 18 + * CC: Programmable color correction 19 + * GAM: Gamma correction 20 + * CSC: Programmable color space conversion 21 + * CBC: Contrast and Brightness control 22 + * SUB: This module performs YCbCr444 to YCbCr420 chrominance subsampling 23 + * RLP: This module performs rounding, range limiting 24 + * and packing of the incoming data 25 + */ 26 + 27 + #include <linux/clk.h> 28 + #include <linux/clkdev.h> 29 + #include <linux/clk-provider.h> 30 + #include <linux/delay.h> 31 + #include <linux/interrupt.h> 32 + #include <linux/module.h> 33 + #include <linux/of.h> 34 + #include <linux/platform_device.h> 35 + #include <linux/pm_runtime.h> 36 + #include <linux/regmap.h> 37 + #include <linux/videodev2.h> 38 + 39 + #include <media/v4l2-device.h> 40 + #include <media/v4l2-image-sizes.h> 41 + #include <media/v4l2-ioctl.h> 42 + #include <media/v4l2-of.h> 43 + #include <media/v4l2-subdev.h> 44 + #include <media/videobuf2-dma-contig.h> 45 + 46 + #include "atmel-isc-regs.h" 47 + 48 + #define ATMEL_ISC_NAME "atmel_isc" 49 + 50 + #define ISC_MAX_SUPPORT_WIDTH 2592 51 + #define ISC_MAX_SUPPORT_HEIGHT 1944 52 + 53 + #define ISC_CLK_MAX_DIV 255 54 + 55 + enum isc_clk_id { 56 + ISC_ISPCK = 0, 57 + ISC_MCK = 1, 58 + }; 59 + 60 + struct isc_clk { 61 + struct clk_hw hw; 62 + struct clk *clk; 63 + struct regmap *regmap; 64 + u8 id; 65 + u8 parent_id; 66 + u32 div; 67 + struct device *dev; 68 + }; 69 + 70 + #define to_isc_clk(hw) container_of(hw, struct isc_clk, hw) 71 + 72 + struct isc_buffer { 73 + struct vb2_v4l2_buffer vb; 74 + struct list_head list; 75 + }; 76 + 77 + struct isc_subdev_entity { 78 + struct v4l2_subdev *sd; 79 + struct v4l2_async_subdev *asd; 80 + struct v4l2_async_notifier notifier; 81 + struct v4l2_subdev_pad_config *config; 82 + 83 + u32 pfe_cfg0; 84 + 85 + struct list_head list; 86 + }; 87 + 88 + /* 89 + * struct isc_format - ISC media bus format information 90 + * @fourcc: Fourcc code for this format 91 + * @mbus_code: V4L2 media bus format code. 92 + * @bpp: Bytes per pixel (when stored in memory) 93 + * @reg_bps: reg value for bits per sample 94 + * (when transferred over a bus) 95 + * @support: Indicates format supported by subdev 96 + */ 97 + struct isc_format { 98 + u32 fourcc; 99 + u32 mbus_code; 100 + u8 bpp; 101 + 102 + u32 reg_bps; 103 + u32 reg_rlp_mode; 104 + u32 reg_dcfg_imode; 105 + u32 reg_dctrl_dview; 106 + 107 + bool support; 108 + }; 109 + 110 + #define ISC_PIPE_LINE_NODE_NUM 11 111 + 112 + struct isc_device { 113 + struct regmap *regmap; 114 + struct clk *hclock; 115 + struct clk *ispck; 116 + struct isc_clk isc_clks[2]; 117 + 118 + struct device *dev; 119 + struct v4l2_device v4l2_dev; 120 + struct video_device video_dev; 121 + 122 + struct vb2_queue vb2_vidq; 123 + spinlock_t dma_queue_lock; 124 + struct list_head dma_queue; 125 + struct isc_buffer *cur_frm; 126 + unsigned int sequence; 127 + bool stop; 128 + struct completion comp; 129 + 130 + struct v4l2_format fmt; 131 + struct isc_format **user_formats; 132 + unsigned int num_user_formats; 133 + const struct isc_format *current_fmt; 134 + 135 + struct mutex lock; 136 + 137 + struct regmap_field *pipeline[ISC_PIPE_LINE_NODE_NUM]; 138 + 139 + struct isc_subdev_entity *current_subdev; 140 + struct list_head subdev_entities; 141 + }; 142 + 143 + static struct isc_format isc_formats[] = { 144 + { V4L2_PIX_FMT_SBGGR8, MEDIA_BUS_FMT_SBGGR8_1X8, 145 + 1, ISC_PFE_CFG0_BPS_EIGHT, ISC_RLP_CFG_MODE_DAT8, 146 + ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, false }, 147 + { V4L2_PIX_FMT_SGBRG8, MEDIA_BUS_FMT_SGBRG8_1X8, 148 + 1, ISC_PFE_CFG0_BPS_EIGHT, ISC_RLP_CFG_MODE_DAT8, 149 + ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, false }, 150 + { V4L2_PIX_FMT_SGRBG8, MEDIA_BUS_FMT_SGRBG8_1X8, 151 + 1, ISC_PFE_CFG0_BPS_EIGHT, ISC_RLP_CFG_MODE_DAT8, 152 + ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, false }, 153 + { V4L2_PIX_FMT_SRGGB8, MEDIA_BUS_FMT_SRGGB8_1X8, 154 + 1, ISC_PFE_CFG0_BPS_EIGHT, ISC_RLP_CFG_MODE_DAT8, 155 + ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, false }, 156 + 157 + { V4L2_PIX_FMT_SBGGR10, MEDIA_BUS_FMT_SBGGR10_1X10, 158 + 2, ISC_PFG_CFG0_BPS_TEN, ISC_RLP_CFG_MODE_DAT10, 159 + ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 160 + { V4L2_PIX_FMT_SGBRG10, MEDIA_BUS_FMT_SGBRG10_1X10, 161 + 2, ISC_PFG_CFG0_BPS_TEN, ISC_RLP_CFG_MODE_DAT10, 162 + ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 163 + { V4L2_PIX_FMT_SGRBG10, MEDIA_BUS_FMT_SGRBG10_1X10, 164 + 2, ISC_PFG_CFG0_BPS_TEN, ISC_RLP_CFG_MODE_DAT10, 165 + ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 166 + { V4L2_PIX_FMT_SRGGB10, MEDIA_BUS_FMT_SRGGB10_1X10, 167 + 2, ISC_PFG_CFG0_BPS_TEN, ISC_RLP_CFG_MODE_DAT10, 168 + ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 169 + 170 + { V4L2_PIX_FMT_SBGGR12, MEDIA_BUS_FMT_SBGGR12_1X12, 171 + 2, ISC_PFG_CFG0_BPS_TWELVE, ISC_RLP_CFG_MODE_DAT12, 172 + ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 173 + { V4L2_PIX_FMT_SGBRG12, MEDIA_BUS_FMT_SGBRG12_1X12, 174 + 2, ISC_PFG_CFG0_BPS_TWELVE, ISC_RLP_CFG_MODE_DAT12, 175 + ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 176 + { V4L2_PIX_FMT_SGRBG12, MEDIA_BUS_FMT_SGRBG12_1X12, 177 + 2, ISC_PFG_CFG0_BPS_TWELVE, ISC_RLP_CFG_MODE_DAT12, 178 + ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 179 + { V4L2_PIX_FMT_SRGGB12, MEDIA_BUS_FMT_SRGGB12_1X12, 180 + 2, ISC_PFG_CFG0_BPS_TWELVE, ISC_RLP_CFG_MODE_DAT12, 181 + ISC_DCFG_IMODE_PACKED16, ISC_DCTRL_DVIEW_PACKED, false }, 182 + 183 + { V4L2_PIX_FMT_YUYV, MEDIA_BUS_FMT_YUYV8_2X8, 184 + 2, ISC_PFE_CFG0_BPS_EIGHT, ISC_RLP_CFG_MODE_DAT8, 185 + ISC_DCFG_IMODE_PACKED8, ISC_DCTRL_DVIEW_PACKED, false }, 186 + }; 187 + 188 + static int isc_clk_enable(struct clk_hw *hw) 189 + { 190 + struct isc_clk *isc_clk = to_isc_clk(hw); 191 + u32 id = isc_clk->id; 192 + struct regmap *regmap = isc_clk->regmap; 193 + 194 + dev_dbg(isc_clk->dev, "ISC CLK: %s, div = %d, parent id = %d\n", 195 + __func__, isc_clk->div, isc_clk->parent_id); 196 + 197 + regmap_update_bits(regmap, ISC_CLKCFG, 198 + ISC_CLKCFG_DIV_MASK(id) | ISC_CLKCFG_SEL_MASK(id), 199 + (isc_clk->div << ISC_CLKCFG_DIV_SHIFT(id)) | 200 + (isc_clk->parent_id << ISC_CLKCFG_SEL_SHIFT(id))); 201 + 202 + regmap_write(regmap, ISC_CLKEN, ISC_CLK(id)); 203 + 204 + return 0; 205 + } 206 + 207 + static void isc_clk_disable(struct clk_hw *hw) 208 + { 209 + struct isc_clk *isc_clk = to_isc_clk(hw); 210 + u32 id = isc_clk->id; 211 + 212 + regmap_write(isc_clk->regmap, ISC_CLKDIS, ISC_CLK(id)); 213 + } 214 + 215 + static int isc_clk_is_enabled(struct clk_hw *hw) 216 + { 217 + struct isc_clk *isc_clk = to_isc_clk(hw); 218 + u32 status; 219 + 220 + regmap_read(isc_clk->regmap, ISC_CLKSR, &status); 221 + 222 + return status & ISC_CLK(isc_clk->id) ? 1 : 0; 223 + } 224 + 225 + static unsigned long 226 + isc_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 227 + { 228 + struct isc_clk *isc_clk = to_isc_clk(hw); 229 + 230 + return DIV_ROUND_CLOSEST(parent_rate, isc_clk->div + 1); 231 + } 232 + 233 + static int isc_clk_determine_rate(struct clk_hw *hw, 234 + struct clk_rate_request *req) 235 + { 236 + struct isc_clk *isc_clk = to_isc_clk(hw); 237 + long best_rate = -EINVAL; 238 + int best_diff = -1; 239 + unsigned int i, div; 240 + 241 + for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 242 + struct clk_hw *parent; 243 + unsigned long parent_rate; 244 + 245 + parent = clk_hw_get_parent_by_index(hw, i); 246 + if (!parent) 247 + continue; 248 + 249 + parent_rate = clk_hw_get_rate(parent); 250 + if (!parent_rate) 251 + continue; 252 + 253 + for (div = 1; div < ISC_CLK_MAX_DIV + 2; div++) { 254 + unsigned long rate; 255 + int diff; 256 + 257 + rate = DIV_ROUND_CLOSEST(parent_rate, div); 258 + diff = abs(req->rate - rate); 259 + 260 + if (best_diff < 0 || best_diff > diff) { 261 + best_rate = rate; 262 + best_diff = diff; 263 + req->best_parent_rate = parent_rate; 264 + req->best_parent_hw = parent; 265 + } 266 + 267 + if (!best_diff || rate < req->rate) 268 + break; 269 + } 270 + 271 + if (!best_diff) 272 + break; 273 + } 274 + 275 + dev_dbg(isc_clk->dev, 276 + "ISC CLK: %s, best_rate = %ld, parent clk: %s @ %ld\n", 277 + __func__, best_rate, 278 + __clk_get_name((req->best_parent_hw)->clk), 279 + req->best_parent_rate); 280 + 281 + if (best_rate < 0) 282 + return best_rate; 283 + 284 + req->rate = best_rate; 285 + 286 + return 0; 287 + } 288 + 289 + static int isc_clk_set_parent(struct clk_hw *hw, u8 index) 290 + { 291 + struct isc_clk *isc_clk = to_isc_clk(hw); 292 + 293 + if (index >= clk_hw_get_num_parents(hw)) 294 + return -EINVAL; 295 + 296 + isc_clk->parent_id = index; 297 + 298 + return 0; 299 + } 300 + 301 + static u8 isc_clk_get_parent(struct clk_hw *hw) 302 + { 303 + struct isc_clk *isc_clk = to_isc_clk(hw); 304 + 305 + return isc_clk->parent_id; 306 + } 307 + 308 + static int isc_clk_set_rate(struct clk_hw *hw, 309 + unsigned long rate, 310 + unsigned long parent_rate) 311 + { 312 + struct isc_clk *isc_clk = to_isc_clk(hw); 313 + u32 div; 314 + 315 + if (!rate) 316 + return -EINVAL; 317 + 318 + div = DIV_ROUND_CLOSEST(parent_rate, rate); 319 + if (div > (ISC_CLK_MAX_DIV + 1) || !div) 320 + return -EINVAL; 321 + 322 + isc_clk->div = div - 1; 323 + 324 + return 0; 325 + } 326 + 327 + static const struct clk_ops isc_clk_ops = { 328 + .enable = isc_clk_enable, 329 + .disable = isc_clk_disable, 330 + .is_enabled = isc_clk_is_enabled, 331 + .recalc_rate = isc_clk_recalc_rate, 332 + .determine_rate = isc_clk_determine_rate, 333 + .set_parent = isc_clk_set_parent, 334 + .get_parent = isc_clk_get_parent, 335 + .set_rate = isc_clk_set_rate, 336 + }; 337 + 338 + static int isc_clk_register(struct isc_device *isc, unsigned int id) 339 + { 340 + struct regmap *regmap = isc->regmap; 341 + struct device_node *np = isc->dev->of_node; 342 + struct isc_clk *isc_clk; 343 + struct clk_init_data init; 344 + const char *clk_name = np->name; 345 + const char *parent_names[3]; 346 + int num_parents; 347 + 348 + num_parents = of_clk_get_parent_count(np); 349 + if (num_parents < 1 || num_parents > 3) 350 + return -EINVAL; 351 + 352 + if (num_parents > 2 && id == ISC_ISPCK) 353 + num_parents = 2; 354 + 355 + of_clk_parent_fill(np, parent_names, num_parents); 356 + 357 + if (id == ISC_MCK) 358 + of_property_read_string(np, "clock-output-names", &clk_name); 359 + else 360 + clk_name = "isc-ispck"; 361 + 362 + init.parent_names = parent_names; 363 + init.num_parents = num_parents; 364 + init.name = clk_name; 365 + init.ops = &isc_clk_ops; 366 + init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE; 367 + 368 + isc_clk = &isc->isc_clks[id]; 369 + isc_clk->hw.init = &init; 370 + isc_clk->regmap = regmap; 371 + isc_clk->id = id; 372 + isc_clk->dev = isc->dev; 373 + 374 + isc_clk->clk = clk_register(isc->dev, &isc_clk->hw); 375 + if (IS_ERR(isc_clk->clk)) { 376 + dev_err(isc->dev, "%s: clock register fail\n", clk_name); 377 + return PTR_ERR(isc_clk->clk); 378 + } else if (id == ISC_MCK) 379 + of_clk_add_provider(np, of_clk_src_simple_get, isc_clk->clk); 380 + 381 + return 0; 382 + } 383 + 384 + static int isc_clk_init(struct isc_device *isc) 385 + { 386 + unsigned int i; 387 + int ret; 388 + 389 + for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) 390 + isc->isc_clks[i].clk = ERR_PTR(-EINVAL); 391 + 392 + for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) { 393 + ret = isc_clk_register(isc, i); 394 + if (ret) 395 + return ret; 396 + } 397 + 398 + return 0; 399 + } 400 + 401 + static void isc_clk_cleanup(struct isc_device *isc) 402 + { 403 + unsigned int i; 404 + 405 + of_clk_del_provider(isc->dev->of_node); 406 + 407 + for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) { 408 + struct isc_clk *isc_clk = &isc->isc_clks[i]; 409 + 410 + if (!IS_ERR(isc_clk->clk)) 411 + clk_unregister(isc_clk->clk); 412 + } 413 + } 414 + 415 + static int isc_queue_setup(struct vb2_queue *vq, 416 + unsigned int *nbuffers, unsigned int *nplanes, 417 + unsigned int sizes[], struct device *alloc_devs[]) 418 + { 419 + struct isc_device *isc = vb2_get_drv_priv(vq); 420 + unsigned int size = isc->fmt.fmt.pix.sizeimage; 421 + 422 + if (*nplanes) 423 + return sizes[0] < size ? -EINVAL : 0; 424 + 425 + *nplanes = 1; 426 + sizes[0] = size; 427 + 428 + return 0; 429 + } 430 + 431 + static int isc_buffer_prepare(struct vb2_buffer *vb) 432 + { 433 + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 434 + struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue); 435 + unsigned long size = isc->fmt.fmt.pix.sizeimage; 436 + 437 + if (vb2_plane_size(vb, 0) < size) { 438 + v4l2_err(&isc->v4l2_dev, "buffer too small (%lu < %lu)\n", 439 + vb2_plane_size(vb, 0), size); 440 + return -EINVAL; 441 + } 442 + 443 + vb2_set_plane_payload(vb, 0, size); 444 + 445 + vbuf->field = isc->fmt.fmt.pix.field; 446 + 447 + return 0; 448 + } 449 + 450 + static inline void isc_start_dma(struct regmap *regmap, 451 + struct isc_buffer *frm, u32 dview) 452 + { 453 + dma_addr_t addr; 454 + 455 + addr = vb2_dma_contig_plane_dma_addr(&frm->vb.vb2_buf, 0); 456 + 457 + regmap_write(regmap, ISC_DCTRL, dview | ISC_DCTRL_IE_IS); 458 + regmap_write(regmap, ISC_DAD0, addr); 459 + regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE); 460 + } 461 + 462 + static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) 463 + { 464 + u32 val; 465 + unsigned int i; 466 + 467 + for (i = 0; i < ISC_PIPE_LINE_NODE_NUM; i++) { 468 + val = pipeline & BIT(i) ? 1 : 0; 469 + regmap_field_write(isc->pipeline[i], val); 470 + } 471 + } 472 + 473 + static int isc_configure(struct isc_device *isc) 474 + { 475 + struct regmap *regmap = isc->regmap; 476 + const struct isc_format *current_fmt = isc->current_fmt; 477 + struct isc_subdev_entity *subdev = isc->current_subdev; 478 + u32 val, mask; 479 + int counter = 10; 480 + 481 + val = current_fmt->reg_bps | subdev->pfe_cfg0 | 482 + ISC_PFE_CFG0_MODE_PROGRESSIVE; 483 + mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW | 484 + ISC_PFE_CFG0_VPOL_LOW | ISC_PFE_CFG0_PPOL_LOW | 485 + ISC_PFE_CFG0_MODE_MASK; 486 + 487 + regmap_update_bits(regmap, ISC_PFE_CFG0, mask, val); 488 + 489 + regmap_update_bits(regmap, ISC_RLP_CFG, ISC_RLP_CFG_MODE_MASK, 490 + current_fmt->reg_rlp_mode); 491 + 492 + regmap_update_bits(regmap, ISC_DCFG, ISC_DCFG_IMODE_MASK, 493 + current_fmt->reg_dcfg_imode); 494 + 495 + /* Disable the pipeline */ 496 + isc_set_pipeline(isc, 0x0); 497 + 498 + /* Update profile */ 499 + regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_UPPRO); 500 + 501 + regmap_read(regmap, ISC_CTRLSR, &val); 502 + while ((val & ISC_CTRL_UPPRO) && counter--) { 503 + usleep_range(1000, 2000); 504 + regmap_read(regmap, ISC_CTRLSR, &val); 505 + } 506 + 507 + if (counter < 0) 508 + return -ETIMEDOUT; 509 + 510 + return 0; 511 + } 512 + 513 + static int isc_start_streaming(struct vb2_queue *vq, unsigned int count) 514 + { 515 + struct isc_device *isc = vb2_get_drv_priv(vq); 516 + struct regmap *regmap = isc->regmap; 517 + struct isc_buffer *buf; 518 + unsigned long flags; 519 + int ret; 520 + u32 val; 521 + 522 + /* Enable stream on the sub device */ 523 + ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1); 524 + if (ret && ret != -ENOIOCTLCMD) { 525 + v4l2_err(&isc->v4l2_dev, "stream on failed in subdev\n"); 526 + goto err_start_stream; 527 + } 528 + 529 + pm_runtime_get_sync(isc->dev); 530 + 531 + /* Disable all the interrupts */ 532 + regmap_write(isc->regmap, ISC_INTDIS, (u32)~0UL); 533 + 534 + /* Clean the interrupt status register */ 535 + regmap_read(regmap, ISC_INTSR, &val); 536 + 537 + ret = isc_configure(isc); 538 + if (unlikely(ret)) 539 + goto err_configure; 540 + 541 + /* Enable DMA interrupt */ 542 + regmap_write(regmap, ISC_INTEN, ISC_INT_DDONE); 543 + 544 + spin_lock_irqsave(&isc->dma_queue_lock, flags); 545 + 546 + isc->sequence = 0; 547 + isc->stop = false; 548 + reinit_completion(&isc->comp); 549 + 550 + isc->cur_frm = list_first_entry(&isc->dma_queue, 551 + struct isc_buffer, list); 552 + list_del(&isc->cur_frm->list); 553 + 554 + isc_start_dma(regmap, isc->cur_frm, isc->current_fmt->reg_dctrl_dview); 555 + 556 + spin_unlock_irqrestore(&isc->dma_queue_lock, flags); 557 + 558 + return 0; 559 + 560 + err_configure: 561 + pm_runtime_put_sync(isc->dev); 562 + 563 + v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0); 564 + 565 + err_start_stream: 566 + spin_lock_irqsave(&isc->dma_queue_lock, flags); 567 + list_for_each_entry(buf, &isc->dma_queue, list) 568 + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); 569 + INIT_LIST_HEAD(&isc->dma_queue); 570 + spin_unlock_irqrestore(&isc->dma_queue_lock, flags); 571 + 572 + return ret; 573 + } 574 + 575 + static void isc_stop_streaming(struct vb2_queue *vq) 576 + { 577 + struct isc_device *isc = vb2_get_drv_priv(vq); 578 + unsigned long flags; 579 + struct isc_buffer *buf; 580 + int ret; 581 + 582 + isc->stop = true; 583 + 584 + /* Wait until the end of the current frame */ 585 + if (isc->cur_frm && !wait_for_completion_timeout(&isc->comp, 5 * HZ)) 586 + v4l2_err(&isc->v4l2_dev, 587 + "Timeout waiting for end of the capture\n"); 588 + 589 + /* Disable DMA interrupt */ 590 + regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE); 591 + 592 + pm_runtime_put_sync(isc->dev); 593 + 594 + /* Disable stream on the sub device */ 595 + ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0); 596 + if (ret && ret != -ENOIOCTLCMD) 597 + v4l2_err(&isc->v4l2_dev, "stream off failed in subdev\n"); 598 + 599 + /* Release all active buffers */ 600 + spin_lock_irqsave(&isc->dma_queue_lock, flags); 601 + if (unlikely(isc->cur_frm)) { 602 + vb2_buffer_done(&isc->cur_frm->vb.vb2_buf, 603 + VB2_BUF_STATE_ERROR); 604 + isc->cur_frm = NULL; 605 + } 606 + list_for_each_entry(buf, &isc->dma_queue, list) 607 + vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); 608 + INIT_LIST_HEAD(&isc->dma_queue); 609 + spin_unlock_irqrestore(&isc->dma_queue_lock, flags); 610 + } 611 + 612 + static void isc_buffer_queue(struct vb2_buffer *vb) 613 + { 614 + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 615 + struct isc_buffer *buf = container_of(vbuf, struct isc_buffer, vb); 616 + struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue); 617 + unsigned long flags; 618 + 619 + spin_lock_irqsave(&isc->dma_queue_lock, flags); 620 + list_add_tail(&buf->list, &isc->dma_queue); 621 + spin_unlock_irqrestore(&isc->dma_queue_lock, flags); 622 + } 623 + 624 + static struct vb2_ops isc_vb2_ops = { 625 + .queue_setup = isc_queue_setup, 626 + .wait_prepare = vb2_ops_wait_prepare, 627 + .wait_finish = vb2_ops_wait_finish, 628 + .buf_prepare = isc_buffer_prepare, 629 + .start_streaming = isc_start_streaming, 630 + .stop_streaming = isc_stop_streaming, 631 + .buf_queue = isc_buffer_queue, 632 + }; 633 + 634 + static int isc_querycap(struct file *file, void *priv, 635 + struct v4l2_capability *cap) 636 + { 637 + struct isc_device *isc = video_drvdata(file); 638 + 639 + strcpy(cap->driver, ATMEL_ISC_NAME); 640 + strcpy(cap->card, "Atmel Image Sensor Controller"); 641 + snprintf(cap->bus_info, sizeof(cap->bus_info), 642 + "platform:%s", isc->v4l2_dev.name); 643 + 644 + return 0; 645 + } 646 + 647 + static int isc_enum_fmt_vid_cap(struct file *file, void *priv, 648 + struct v4l2_fmtdesc *f) 649 + { 650 + struct isc_device *isc = video_drvdata(file); 651 + u32 index = f->index; 652 + 653 + if (index >= isc->num_user_formats) 654 + return -EINVAL; 655 + 656 + f->pixelformat = isc->user_formats[index]->fourcc; 657 + 658 + return 0; 659 + } 660 + 661 + static int isc_g_fmt_vid_cap(struct file *file, void *priv, 662 + struct v4l2_format *fmt) 663 + { 664 + struct isc_device *isc = video_drvdata(file); 665 + 666 + *fmt = isc->fmt; 667 + 668 + return 0; 669 + } 670 + 671 + static struct isc_format *find_format_by_fourcc(struct isc_device *isc, 672 + unsigned int fourcc) 673 + { 674 + unsigned int num_formats = isc->num_user_formats; 675 + struct isc_format *fmt; 676 + unsigned int i; 677 + 678 + for (i = 0; i < num_formats; i++) { 679 + fmt = isc->user_formats[i]; 680 + if (fmt->fourcc == fourcc) 681 + return fmt; 682 + } 683 + 684 + return NULL; 685 + } 686 + 687 + static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, 688 + struct isc_format **current_fmt) 689 + { 690 + struct isc_format *isc_fmt; 691 + struct v4l2_pix_format *pixfmt = &f->fmt.pix; 692 + struct v4l2_subdev_format format = { 693 + .which = V4L2_SUBDEV_FORMAT_TRY, 694 + }; 695 + int ret; 696 + 697 + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 698 + return -EINVAL; 699 + 700 + isc_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat); 701 + if (!isc_fmt) { 702 + v4l2_warn(&isc->v4l2_dev, "Format 0x%x not found\n", 703 + pixfmt->pixelformat); 704 + isc_fmt = isc->user_formats[isc->num_user_formats - 1]; 705 + pixfmt->pixelformat = isc_fmt->fourcc; 706 + } 707 + 708 + /* Limit to Atmel ISC hardware capabilities */ 709 + if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) 710 + pixfmt->width = ISC_MAX_SUPPORT_WIDTH; 711 + if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) 712 + pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; 713 + 714 + v4l2_fill_mbus_format(&format.format, pixfmt, isc_fmt->mbus_code); 715 + ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt, 716 + isc->current_subdev->config, &format); 717 + if (ret < 0) 718 + return ret; 719 + 720 + v4l2_fill_pix_format(pixfmt, &format.format); 721 + 722 + pixfmt->field = V4L2_FIELD_NONE; 723 + pixfmt->bytesperline = pixfmt->width * isc_fmt->bpp; 724 + pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; 725 + 726 + if (current_fmt) 727 + *current_fmt = isc_fmt; 728 + 729 + return 0; 730 + } 731 + 732 + static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) 733 + { 734 + struct v4l2_subdev_format format = { 735 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 736 + }; 737 + struct isc_format *current_fmt; 738 + int ret; 739 + 740 + ret = isc_try_fmt(isc, f, &current_fmt); 741 + if (ret) 742 + return ret; 743 + 744 + v4l2_fill_mbus_format(&format.format, &f->fmt.pix, 745 + current_fmt->mbus_code); 746 + ret = v4l2_subdev_call(isc->current_subdev->sd, pad, 747 + set_fmt, NULL, &format); 748 + if (ret < 0) 749 + return ret; 750 + 751 + isc->fmt = *f; 752 + isc->current_fmt = current_fmt; 753 + 754 + return 0; 755 + } 756 + 757 + static int isc_s_fmt_vid_cap(struct file *file, void *priv, 758 + struct v4l2_format *f) 759 + { 760 + struct isc_device *isc = video_drvdata(file); 761 + 762 + if (vb2_is_streaming(&isc->vb2_vidq)) 763 + return -EBUSY; 764 + 765 + return isc_set_fmt(isc, f); 766 + } 767 + 768 + static int isc_try_fmt_vid_cap(struct file *file, void *priv, 769 + struct v4l2_format *f) 770 + { 771 + struct isc_device *isc = video_drvdata(file); 772 + 773 + return isc_try_fmt(isc, f, NULL); 774 + } 775 + 776 + static int isc_enum_input(struct file *file, void *priv, 777 + struct v4l2_input *inp) 778 + { 779 + if (inp->index != 0) 780 + return -EINVAL; 781 + 782 + inp->type = V4L2_INPUT_TYPE_CAMERA; 783 + inp->std = 0; 784 + strcpy(inp->name, "Camera"); 785 + 786 + return 0; 787 + } 788 + 789 + static int isc_g_input(struct file *file, void *priv, unsigned int *i) 790 + { 791 + *i = 0; 792 + 793 + return 0; 794 + } 795 + 796 + static int isc_s_input(struct file *file, void *priv, unsigned int i) 797 + { 798 + if (i > 0) 799 + return -EINVAL; 800 + 801 + return 0; 802 + } 803 + 804 + static int isc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 805 + { 806 + struct isc_device *isc = video_drvdata(file); 807 + 808 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 809 + return -EINVAL; 810 + 811 + return v4l2_subdev_call(isc->current_subdev->sd, video, g_parm, a); 812 + } 813 + 814 + static int isc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) 815 + { 816 + struct isc_device *isc = video_drvdata(file); 817 + 818 + if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 819 + return -EINVAL; 820 + 821 + return v4l2_subdev_call(isc->current_subdev->sd, video, s_parm, a); 822 + } 823 + 824 + static int isc_enum_framesizes(struct file *file, void *fh, 825 + struct v4l2_frmsizeenum *fsize) 826 + { 827 + struct isc_device *isc = video_drvdata(file); 828 + const struct isc_format *isc_fmt; 829 + struct v4l2_subdev_frame_size_enum fse = { 830 + .index = fsize->index, 831 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 832 + }; 833 + int ret; 834 + 835 + isc_fmt = find_format_by_fourcc(isc, fsize->pixel_format); 836 + if (!isc_fmt) 837 + return -EINVAL; 838 + 839 + fse.code = isc_fmt->mbus_code; 840 + 841 + ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size, 842 + NULL, &fse); 843 + if (ret) 844 + return ret; 845 + 846 + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; 847 + fsize->discrete.width = fse.max_width; 848 + fsize->discrete.height = fse.max_height; 849 + 850 + return 0; 851 + } 852 + 853 + static int isc_enum_frameintervals(struct file *file, void *fh, 854 + struct v4l2_frmivalenum *fival) 855 + { 856 + struct isc_device *isc = video_drvdata(file); 857 + const struct isc_format *isc_fmt; 858 + struct v4l2_subdev_frame_interval_enum fie = { 859 + .index = fival->index, 860 + .width = fival->width, 861 + .height = fival->height, 862 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 863 + }; 864 + int ret; 865 + 866 + isc_fmt = find_format_by_fourcc(isc, fival->pixel_format); 867 + if (!isc_fmt) 868 + return -EINVAL; 869 + 870 + fie.code = isc_fmt->mbus_code; 871 + 872 + ret = v4l2_subdev_call(isc->current_subdev->sd, pad, 873 + enum_frame_interval, NULL, &fie); 874 + if (ret) 875 + return ret; 876 + 877 + fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; 878 + fival->discrete = fie.interval; 879 + 880 + return 0; 881 + } 882 + 883 + static const struct v4l2_ioctl_ops isc_ioctl_ops = { 884 + .vidioc_querycap = isc_querycap, 885 + .vidioc_enum_fmt_vid_cap = isc_enum_fmt_vid_cap, 886 + .vidioc_g_fmt_vid_cap = isc_g_fmt_vid_cap, 887 + .vidioc_s_fmt_vid_cap = isc_s_fmt_vid_cap, 888 + .vidioc_try_fmt_vid_cap = isc_try_fmt_vid_cap, 889 + 890 + .vidioc_enum_input = isc_enum_input, 891 + .vidioc_g_input = isc_g_input, 892 + .vidioc_s_input = isc_s_input, 893 + 894 + .vidioc_reqbufs = vb2_ioctl_reqbufs, 895 + .vidioc_querybuf = vb2_ioctl_querybuf, 896 + .vidioc_qbuf = vb2_ioctl_qbuf, 897 + .vidioc_expbuf = vb2_ioctl_expbuf, 898 + .vidioc_dqbuf = vb2_ioctl_dqbuf, 899 + .vidioc_create_bufs = vb2_ioctl_create_bufs, 900 + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, 901 + .vidioc_streamon = vb2_ioctl_streamon, 902 + .vidioc_streamoff = vb2_ioctl_streamoff, 903 + 904 + .vidioc_g_parm = isc_g_parm, 905 + .vidioc_s_parm = isc_s_parm, 906 + .vidioc_enum_framesizes = isc_enum_framesizes, 907 + .vidioc_enum_frameintervals = isc_enum_frameintervals, 908 + }; 909 + 910 + static int isc_open(struct file *file) 911 + { 912 + struct isc_device *isc = video_drvdata(file); 913 + struct v4l2_subdev *sd = isc->current_subdev->sd; 914 + int ret; 915 + 916 + if (mutex_lock_interruptible(&isc->lock)) 917 + return -ERESTARTSYS; 918 + 919 + ret = v4l2_fh_open(file); 920 + if (ret < 0) 921 + goto unlock; 922 + 923 + if (!v4l2_fh_is_singular_file(file)) 924 + goto unlock; 925 + 926 + ret = v4l2_subdev_call(sd, core, s_power, 1); 927 + if (ret < 0 && ret != -ENOIOCTLCMD) 928 + v4l2_fh_release(file); 929 + else 930 + ret = 0; 931 + 932 + unlock: 933 + mutex_unlock(&isc->lock); 934 + return ret; 935 + } 936 + 937 + static int isc_release(struct file *file) 938 + { 939 + struct isc_device *isc = video_drvdata(file); 940 + struct v4l2_subdev *sd = isc->current_subdev->sd; 941 + bool fh_singular; 942 + int ret; 943 + 944 + mutex_lock(&isc->lock); 945 + 946 + fh_singular = v4l2_fh_is_singular_file(file); 947 + 948 + ret = _vb2_fop_release(file, NULL); 949 + 950 + if (fh_singular) 951 + v4l2_subdev_call(sd, core, s_power, 0); 952 + 953 + mutex_unlock(&isc->lock); 954 + 955 + return ret; 956 + } 957 + 958 + static const struct v4l2_file_operations isc_fops = { 959 + .owner = THIS_MODULE, 960 + .open = isc_open, 961 + .release = isc_release, 962 + .unlocked_ioctl = video_ioctl2, 963 + .read = vb2_fop_read, 964 + .mmap = vb2_fop_mmap, 965 + .poll = vb2_fop_poll, 966 + }; 967 + 968 + static irqreturn_t isc_interrupt(int irq, void *dev_id) 969 + { 970 + struct isc_device *isc = (struct isc_device *)dev_id; 971 + struct regmap *regmap = isc->regmap; 972 + u32 isc_intsr, isc_intmask, pending; 973 + irqreturn_t ret = IRQ_NONE; 974 + 975 + spin_lock(&isc->dma_queue_lock); 976 + 977 + regmap_read(regmap, ISC_INTSR, &isc_intsr); 978 + regmap_read(regmap, ISC_INTMASK, &isc_intmask); 979 + 980 + pending = isc_intsr & isc_intmask; 981 + 982 + if (likely(pending & ISC_INT_DDONE)) { 983 + if (isc->cur_frm) { 984 + struct vb2_v4l2_buffer *vbuf = &isc->cur_frm->vb; 985 + struct vb2_buffer *vb = &vbuf->vb2_buf; 986 + 987 + vb->timestamp = ktime_get_ns(); 988 + vbuf->sequence = isc->sequence++; 989 + vb2_buffer_done(vb, VB2_BUF_STATE_DONE); 990 + isc->cur_frm = NULL; 991 + } 992 + 993 + if (!list_empty(&isc->dma_queue) && !isc->stop) { 994 + isc->cur_frm = list_first_entry(&isc->dma_queue, 995 + struct isc_buffer, list); 996 + list_del(&isc->cur_frm->list); 997 + 998 + isc_start_dma(regmap, isc->cur_frm, 999 + isc->current_fmt->reg_dctrl_dview); 1000 + } 1001 + 1002 + if (isc->stop) 1003 + complete(&isc->comp); 1004 + 1005 + ret = IRQ_HANDLED; 1006 + } 1007 + 1008 + spin_unlock(&isc->dma_queue_lock); 1009 + 1010 + return ret; 1011 + } 1012 + 1013 + static int isc_async_bound(struct v4l2_async_notifier *notifier, 1014 + struct v4l2_subdev *subdev, 1015 + struct v4l2_async_subdev *asd) 1016 + { 1017 + struct isc_device *isc = container_of(notifier->v4l2_dev, 1018 + struct isc_device, v4l2_dev); 1019 + struct isc_subdev_entity *subdev_entity = 1020 + container_of(notifier, struct isc_subdev_entity, notifier); 1021 + 1022 + if (video_is_registered(&isc->video_dev)) { 1023 + v4l2_err(&isc->v4l2_dev, "only supports one sub-device.\n"); 1024 + return -EBUSY; 1025 + } 1026 + 1027 + subdev_entity->sd = subdev; 1028 + 1029 + return 0; 1030 + } 1031 + 1032 + static void isc_async_unbind(struct v4l2_async_notifier *notifier, 1033 + struct v4l2_subdev *subdev, 1034 + struct v4l2_async_subdev *asd) 1035 + { 1036 + struct isc_device *isc = container_of(notifier->v4l2_dev, 1037 + struct isc_device, v4l2_dev); 1038 + 1039 + video_unregister_device(&isc->video_dev); 1040 + if (isc->current_subdev->config) 1041 + v4l2_subdev_free_pad_config(isc->current_subdev->config); 1042 + } 1043 + 1044 + static struct isc_format *find_format_by_code(unsigned int code, int *index) 1045 + { 1046 + struct isc_format *fmt = &isc_formats[0]; 1047 + unsigned int i; 1048 + 1049 + for (i = 0; i < ARRAY_SIZE(isc_formats); i++) { 1050 + if (fmt->mbus_code == code) { 1051 + *index = i; 1052 + return fmt; 1053 + } 1054 + 1055 + fmt++; 1056 + } 1057 + 1058 + return NULL; 1059 + } 1060 + 1061 + static int isc_formats_init(struct isc_device *isc) 1062 + { 1063 + struct isc_format *fmt; 1064 + struct v4l2_subdev *subdev = isc->current_subdev->sd; 1065 + int num_fmts = 0, i, j; 1066 + struct v4l2_subdev_mbus_code_enum mbus_code = { 1067 + .which = V4L2_SUBDEV_FORMAT_ACTIVE, 1068 + }; 1069 + 1070 + fmt = &isc_formats[0]; 1071 + for (i = 0; i < ARRAY_SIZE(isc_formats); i++) { 1072 + fmt->support = false; 1073 + fmt++; 1074 + } 1075 + 1076 + while (!v4l2_subdev_call(subdev, pad, enum_mbus_code, 1077 + NULL, &mbus_code)) { 1078 + mbus_code.index++; 1079 + fmt = find_format_by_code(mbus_code.code, &i); 1080 + if (!fmt) 1081 + continue; 1082 + 1083 + fmt->support = true; 1084 + num_fmts++; 1085 + } 1086 + 1087 + if (!num_fmts) 1088 + return -ENXIO; 1089 + 1090 + isc->num_user_formats = num_fmts; 1091 + isc->user_formats = devm_kcalloc(isc->dev, 1092 + num_fmts, sizeof(struct isc_format *), 1093 + GFP_KERNEL); 1094 + if (!isc->user_formats) { 1095 + v4l2_err(&isc->v4l2_dev, "could not allocate memory\n"); 1096 + return -ENOMEM; 1097 + } 1098 + 1099 + fmt = &isc_formats[0]; 1100 + for (i = 0, j = 0; i < ARRAY_SIZE(isc_formats); i++) { 1101 + if (fmt->support) 1102 + isc->user_formats[j++] = fmt; 1103 + 1104 + fmt++; 1105 + } 1106 + 1107 + return 0; 1108 + } 1109 + 1110 + static int isc_set_default_fmt(struct isc_device *isc) 1111 + { 1112 + struct v4l2_format f = { 1113 + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 1114 + .fmt.pix = { 1115 + .width = VGA_WIDTH, 1116 + .height = VGA_HEIGHT, 1117 + .field = V4L2_FIELD_NONE, 1118 + .pixelformat = isc->user_formats[0]->fourcc, 1119 + }, 1120 + }; 1121 + 1122 + return isc_set_fmt(isc, &f); 1123 + } 1124 + 1125 + static int isc_async_complete(struct v4l2_async_notifier *notifier) 1126 + { 1127 + struct isc_device *isc = container_of(notifier->v4l2_dev, 1128 + struct isc_device, v4l2_dev); 1129 + struct isc_subdev_entity *sd_entity; 1130 + struct video_device *vdev = &isc->video_dev; 1131 + struct vb2_queue *q = &isc->vb2_vidq; 1132 + int ret; 1133 + 1134 + isc->current_subdev = container_of(notifier, 1135 + struct isc_subdev_entity, notifier); 1136 + sd_entity = isc->current_subdev; 1137 + 1138 + mutex_init(&isc->lock); 1139 + init_completion(&isc->comp); 1140 + 1141 + /* Initialize videobuf2 queue */ 1142 + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1143 + q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; 1144 + q->drv_priv = isc; 1145 + q->buf_struct_size = sizeof(struct isc_buffer); 1146 + q->ops = &isc_vb2_ops; 1147 + q->mem_ops = &vb2_dma_contig_memops; 1148 + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 1149 + q->lock = &isc->lock; 1150 + q->min_buffers_needed = 1; 1151 + q->dev = isc->dev; 1152 + 1153 + ret = vb2_queue_init(q); 1154 + if (ret < 0) { 1155 + v4l2_err(&isc->v4l2_dev, 1156 + "vb2_queue_init() failed: %d\n", ret); 1157 + return ret; 1158 + } 1159 + 1160 + /* Init video dma queues */ 1161 + INIT_LIST_HEAD(&isc->dma_queue); 1162 + spin_lock_init(&isc->dma_queue_lock); 1163 + 1164 + sd_entity->config = v4l2_subdev_alloc_pad_config(sd_entity->sd); 1165 + if (sd_entity->config == NULL) 1166 + return -ENOMEM; 1167 + 1168 + ret = isc_formats_init(isc); 1169 + if (ret < 0) { 1170 + v4l2_err(&isc->v4l2_dev, 1171 + "Init format failed: %d\n", ret); 1172 + return ret; 1173 + } 1174 + 1175 + ret = v4l2_subdev_call(sd_entity->sd, core, s_power, 1); 1176 + if (ret < 0 && ret != -ENOIOCTLCMD) 1177 + return ret; 1178 + 1179 + ret = isc_set_default_fmt(isc); 1180 + if (ret) { 1181 + v4l2_err(&isc->v4l2_dev, "Could not set default format\n"); 1182 + return ret; 1183 + } 1184 + 1185 + ret = v4l2_subdev_call(sd_entity->sd, core, s_power, 0); 1186 + if (ret < 0 && ret != -ENOIOCTLCMD) 1187 + return ret; 1188 + 1189 + /* Register video device */ 1190 + strlcpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name)); 1191 + vdev->release = video_device_release_empty; 1192 + vdev->fops = &isc_fops; 1193 + vdev->ioctl_ops = &isc_ioctl_ops; 1194 + vdev->v4l2_dev = &isc->v4l2_dev; 1195 + vdev->vfl_dir = VFL_DIR_RX; 1196 + vdev->queue = q; 1197 + vdev->lock = &isc->lock; 1198 + vdev->ctrl_handler = isc->current_subdev->sd->ctrl_handler; 1199 + vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; 1200 + video_set_drvdata(vdev, isc); 1201 + 1202 + ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); 1203 + if (ret < 0) { 1204 + v4l2_err(&isc->v4l2_dev, 1205 + "video_register_device failed: %d\n", ret); 1206 + return ret; 1207 + } 1208 + 1209 + return 0; 1210 + } 1211 + 1212 + static void isc_subdev_cleanup(struct isc_device *isc) 1213 + { 1214 + struct isc_subdev_entity *subdev_entity; 1215 + 1216 + list_for_each_entry(subdev_entity, &isc->subdev_entities, list) 1217 + v4l2_async_notifier_unregister(&subdev_entity->notifier); 1218 + 1219 + INIT_LIST_HEAD(&isc->subdev_entities); 1220 + } 1221 + 1222 + static int isc_pipeline_init(struct isc_device *isc) 1223 + { 1224 + struct device *dev = isc->dev; 1225 + struct regmap *regmap = isc->regmap; 1226 + struct regmap_field *regs; 1227 + unsigned int i; 1228 + 1229 + /* WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB422-->SUB420 */ 1230 + const struct reg_field regfields[ISC_PIPE_LINE_NODE_NUM] = { 1231 + REG_FIELD(ISC_WB_CTRL, 0, 0), 1232 + REG_FIELD(ISC_CFA_CTRL, 0, 0), 1233 + REG_FIELD(ISC_CC_CTRL, 0, 0), 1234 + REG_FIELD(ISC_GAM_CTRL, 0, 0), 1235 + REG_FIELD(ISC_GAM_CTRL, 1, 1), 1236 + REG_FIELD(ISC_GAM_CTRL, 2, 2), 1237 + REG_FIELD(ISC_GAM_CTRL, 3, 3), 1238 + REG_FIELD(ISC_CSC_CTRL, 0, 0), 1239 + REG_FIELD(ISC_CBC_CTRL, 0, 0), 1240 + REG_FIELD(ISC_SUB422_CTRL, 0, 0), 1241 + REG_FIELD(ISC_SUB420_CTRL, 0, 0), 1242 + }; 1243 + 1244 + for (i = 0; i < ISC_PIPE_LINE_NODE_NUM; i++) { 1245 + regs = devm_regmap_field_alloc(dev, regmap, regfields[i]); 1246 + if (IS_ERR(regs)) 1247 + return PTR_ERR(regs); 1248 + 1249 + isc->pipeline[i] = regs; 1250 + } 1251 + 1252 + return 0; 1253 + } 1254 + 1255 + static int isc_parse_dt(struct device *dev, struct isc_device *isc) 1256 + { 1257 + struct device_node *np = dev->of_node; 1258 + struct device_node *epn = NULL, *rem; 1259 + struct v4l2_of_endpoint v4l2_epn; 1260 + struct isc_subdev_entity *subdev_entity; 1261 + unsigned int flags; 1262 + int ret; 1263 + 1264 + INIT_LIST_HEAD(&isc->subdev_entities); 1265 + 1266 + for (; ;) { 1267 + epn = of_graph_get_next_endpoint(np, epn); 1268 + if (!epn) 1269 + break; 1270 + 1271 + rem = of_graph_get_remote_port_parent(epn); 1272 + if (!rem) { 1273 + dev_notice(dev, "Remote device at %s not found\n", 1274 + of_node_full_name(epn)); 1275 + continue; 1276 + } 1277 + 1278 + ret = v4l2_of_parse_endpoint(epn, &v4l2_epn); 1279 + if (ret) { 1280 + of_node_put(rem); 1281 + ret = -EINVAL; 1282 + dev_err(dev, "Could not parse the endpoint\n"); 1283 + break; 1284 + } 1285 + 1286 + subdev_entity = devm_kzalloc(dev, 1287 + sizeof(*subdev_entity), GFP_KERNEL); 1288 + if (subdev_entity == NULL) { 1289 + of_node_put(rem); 1290 + ret = -ENOMEM; 1291 + break; 1292 + } 1293 + 1294 + subdev_entity->asd = devm_kzalloc(dev, 1295 + sizeof(*subdev_entity->asd), GFP_KERNEL); 1296 + if (subdev_entity->asd == NULL) { 1297 + of_node_put(rem); 1298 + ret = -ENOMEM; 1299 + break; 1300 + } 1301 + 1302 + flags = v4l2_epn.bus.parallel.flags; 1303 + 1304 + if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) 1305 + subdev_entity->pfe_cfg0 = ISC_PFE_CFG0_HPOL_LOW; 1306 + 1307 + if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) 1308 + subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_VPOL_LOW; 1309 + 1310 + if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) 1311 + subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW; 1312 + 1313 + subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_OF; 1314 + subdev_entity->asd->match.of.node = rem; 1315 + list_add_tail(&subdev_entity->list, &isc->subdev_entities); 1316 + } 1317 + 1318 + of_node_put(epn); 1319 + return ret; 1320 + } 1321 + 1322 + /* regmap configuration */ 1323 + #define ATMEL_ISC_REG_MAX 0xbfc 1324 + static const struct regmap_config isc_regmap_config = { 1325 + .reg_bits = 32, 1326 + .reg_stride = 4, 1327 + .val_bits = 32, 1328 + .max_register = ATMEL_ISC_REG_MAX, 1329 + }; 1330 + 1331 + static int atmel_isc_probe(struct platform_device *pdev) 1332 + { 1333 + struct device *dev = &pdev->dev; 1334 + struct isc_device *isc; 1335 + struct resource *res; 1336 + void __iomem *io_base; 1337 + struct isc_subdev_entity *subdev_entity; 1338 + int irq; 1339 + int ret; 1340 + 1341 + isc = devm_kzalloc(dev, sizeof(*isc), GFP_KERNEL); 1342 + if (!isc) 1343 + return -ENOMEM; 1344 + 1345 + platform_set_drvdata(pdev, isc); 1346 + isc->dev = dev; 1347 + 1348 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1349 + io_base = devm_ioremap_resource(dev, res); 1350 + if (IS_ERR(io_base)) 1351 + return PTR_ERR(io_base); 1352 + 1353 + isc->regmap = devm_regmap_init_mmio(dev, io_base, &isc_regmap_config); 1354 + if (IS_ERR(isc->regmap)) { 1355 + ret = PTR_ERR(isc->regmap); 1356 + dev_err(dev, "failed to init register map: %d\n", ret); 1357 + return ret; 1358 + } 1359 + 1360 + irq = platform_get_irq(pdev, 0); 1361 + if (IS_ERR_VALUE(irq)) { 1362 + ret = irq; 1363 + dev_err(dev, "failed to get irq: %d\n", ret); 1364 + return ret; 1365 + } 1366 + 1367 + ret = devm_request_irq(dev, irq, isc_interrupt, 0, 1368 + ATMEL_ISC_NAME, isc); 1369 + if (ret < 0) { 1370 + dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n", 1371 + irq, ret); 1372 + return ret; 1373 + } 1374 + 1375 + ret = isc_pipeline_init(isc); 1376 + if (ret) 1377 + return ret; 1378 + 1379 + isc->hclock = devm_clk_get(dev, "hclock"); 1380 + if (IS_ERR(isc->hclock)) { 1381 + ret = PTR_ERR(isc->hclock); 1382 + dev_err(dev, "failed to get hclock: %d\n", ret); 1383 + return ret; 1384 + } 1385 + 1386 + ret = isc_clk_init(isc); 1387 + if (ret) { 1388 + dev_err(dev, "failed to init isc clock: %d\n", ret); 1389 + goto clean_isc_clk; 1390 + } 1391 + 1392 + isc->ispck = isc->isc_clks[ISC_ISPCK].clk; 1393 + 1394 + /* ispck should be greater or equal to hclock */ 1395 + ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock)); 1396 + if (ret) { 1397 + dev_err(dev, "failed to set ispck rate: %d\n", ret); 1398 + goto clean_isc_clk; 1399 + } 1400 + 1401 + ret = v4l2_device_register(dev, &isc->v4l2_dev); 1402 + if (ret) { 1403 + dev_err(dev, "unable to register v4l2 device.\n"); 1404 + goto clean_isc_clk; 1405 + } 1406 + 1407 + ret = isc_parse_dt(dev, isc); 1408 + if (ret) { 1409 + dev_err(dev, "fail to parse device tree\n"); 1410 + goto unregister_v4l2_device; 1411 + } 1412 + 1413 + if (list_empty(&isc->subdev_entities)) { 1414 + dev_err(dev, "no subdev found\n"); 1415 + goto unregister_v4l2_device; 1416 + } 1417 + 1418 + list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { 1419 + subdev_entity->notifier.subdevs = &subdev_entity->asd; 1420 + subdev_entity->notifier.num_subdevs = 1; 1421 + subdev_entity->notifier.bound = isc_async_bound; 1422 + subdev_entity->notifier.unbind = isc_async_unbind; 1423 + subdev_entity->notifier.complete = isc_async_complete; 1424 + 1425 + ret = v4l2_async_notifier_register(&isc->v4l2_dev, 1426 + &subdev_entity->notifier); 1427 + if (ret) { 1428 + dev_err(dev, "fail to register async notifier\n"); 1429 + goto cleanup_subdev; 1430 + } 1431 + 1432 + if (video_is_registered(&isc->video_dev)) 1433 + break; 1434 + } 1435 + 1436 + pm_runtime_enable(dev); 1437 + 1438 + return 0; 1439 + 1440 + cleanup_subdev: 1441 + isc_subdev_cleanup(isc); 1442 + 1443 + unregister_v4l2_device: 1444 + v4l2_device_unregister(&isc->v4l2_dev); 1445 + 1446 + clean_isc_clk: 1447 + isc_clk_cleanup(isc); 1448 + 1449 + return ret; 1450 + } 1451 + 1452 + static int atmel_isc_remove(struct platform_device *pdev) 1453 + { 1454 + struct isc_device *isc = platform_get_drvdata(pdev); 1455 + 1456 + pm_runtime_disable(&pdev->dev); 1457 + 1458 + isc_subdev_cleanup(isc); 1459 + 1460 + v4l2_device_unregister(&isc->v4l2_dev); 1461 + 1462 + isc_clk_cleanup(isc); 1463 + 1464 + return 0; 1465 + } 1466 + 1467 + static int isc_runtime_suspend(struct device *dev) 1468 + { 1469 + struct isc_device *isc = dev_get_drvdata(dev); 1470 + 1471 + clk_disable_unprepare(isc->ispck); 1472 + clk_disable_unprepare(isc->hclock); 1473 + 1474 + return 0; 1475 + } 1476 + 1477 + static int isc_runtime_resume(struct device *dev) 1478 + { 1479 + struct isc_device *isc = dev_get_drvdata(dev); 1480 + int ret; 1481 + 1482 + ret = clk_prepare_enable(isc->hclock); 1483 + if (ret) 1484 + return ret; 1485 + 1486 + return clk_prepare_enable(isc->ispck); 1487 + } 1488 + 1489 + static const struct dev_pm_ops atmel_isc_dev_pm_ops = { 1490 + SET_RUNTIME_PM_OPS(isc_runtime_suspend, isc_runtime_resume, NULL) 1491 + }; 1492 + 1493 + static const struct of_device_id atmel_isc_of_match[] = { 1494 + { .compatible = "atmel,sama5d2-isc" }, 1495 + { } 1496 + }; 1497 + MODULE_DEVICE_TABLE(of, atmel_isc_of_match); 1498 + 1499 + static struct platform_driver atmel_isc_driver = { 1500 + .probe = atmel_isc_probe, 1501 + .remove = atmel_isc_remove, 1502 + .driver = { 1503 + .name = ATMEL_ISC_NAME, 1504 + .pm = &atmel_isc_dev_pm_ops, 1505 + .of_match_table = of_match_ptr(atmel_isc_of_match), 1506 + }, 1507 + }; 1508 + 1509 + module_platform_driver(atmel_isc_driver); 1510 + 1511 + MODULE_AUTHOR("Songjun Wu <songjun.wu@microchip.com>"); 1512 + MODULE_DESCRIPTION("The V4L2 driver for Atmel-ISC"); 1513 + MODULE_LICENSE("GPL v2"); 1514 + MODULE_SUPPORTED_DEVICE("video");