1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2026 Renesas Electronics Corp. 4 * Copyright (C) 2026 Ideas on Board Oy 5 * Copyright (C) 2026 Ragnatech AB 6 */ 7 8 #include "rpp_module.h" 9 10 #define ACQ_VERSION_REG 0x0000 11 12 #define ACQ_CTRL_REG 0x0004 13 #define ACQ_CTRL_ALTERNATIVE_CFG_MODE_ENABLE BIT(8) 14 #define ACQ_CTRL_RPP_MODE_MASK GENMASK(3, 1) 15 #define ACQ_CTRL_RPP_MODE_RAWBT601 (0 << 1) 16 #define ACQ_CTRL_RPP_MODE_BT656 (1 << 1) 17 #define ACQ_CTRL_RPP_MODE_BT601 (2 << 1) 18 #define ACQ_CTRL_RPP_MODE_BAYER (3 << 1) 19 #define ACQ_CTRL_RPP_MODE_DATA (4 << 1) 20 #define ACQ_CTRL_RPP_MODE_BAYERRGB (5 << 1) 21 #define ACQ_CTRL_RPP_MODE_RAWBT656 (6 << 1) 22 #define ACQ_CTRL_INFORM_EN_ENABLE BIT(0) 23 24 #define ACQ_PROP_REG 0x0008 25 26 #define ACQ_PROP_SENSOR_IN_LSB_ALIGNED_IN_LSB BIT(30) 27 #define ACQ_PROP_YUV_OUT_SEL BIT(25) 28 #define ACQ_PROP_MUX_DMA_SEL BIT(24) 29 #define ACQ_PROP_SECOND_INPUT_TYPE BIT(18) 30 #define ACQ_PROP_LATENCY_FIFO_INPUT_SELECTION BIT(15) 31 #define ACQ_PROP_INPUT_SELECTION_MASK GENMASK(14, 12) 32 #define ACQ_PROP_INPUT_SELECTION_8BIT (0 << 12) 33 #define ACQ_PROP_INPUT_SELECTION_10BIT (1 << 12) 34 #define ACQ_PROP_INPUT_SELECTION_12BIT (2 << 12) 35 #define ACQ_PROP_BAYER_PAT_MASK GENMASK(4, 3) 36 #define ACQ_PROP_BAYER_PAT_RGRG (0 << 3) 37 #define ACQ_PROP_BAYER_PAT_GRGR (1 << 3) 38 #define ACQ_PROP_BAYER_PAT_GBGB (2 << 3) 39 #define ACQ_PROP_BAYER_PAT_BGBG (3 << 3) 40 #define ACQ_PROP_VSYNC_POL BIT(2) 41 #define ACQ_PROP_HSYNC_POL BIT(1) 42 #define ACQ_PROP_SAMPLE_EDGE BIT(0) 43 44 #define ACQ_H_OFFS_REG 0x000c 45 #define ACQ_V_OFFS_REG 0x0010 46 #define ACQ_H_SIZE_REG 0x0014 47 #define ACQ_V_SIZE_REG 0x0018 48 #define ACQ_OUT_H_OFFS_REG 0x001c 49 #define ACQ_OUT_V_OFFS_REG 0x0020 50 #define ACQ_OUT_H_SIZE_REG 0x0024 51 #define ACQ_OUT_V_SIZE_REG 0x0028 52 #define FLAGS_SHD_REG 0x002c 53 #define ACQ_OUT_H_OFFS_SHD_REG 0x0030 54 #define ACQ_OUT_V_OFFS_SHD_REG 0x0034 55 #define ACQ_OUT_H_SIZE_SHD_REG 0x0038 56 #define ACQ_OUT_V_SIZE_SHD_REG 0x003c 57 58 static int rppx1_acq_probe(struct rpp_module *mod) 59 { 60 /* Version check. */ 61 if (rpp_module_read(mod, ACQ_VERSION_REG) != 0x0b) 62 return -EINVAL; 63 64 return 0; 65 } 66 67 static int rppx1_acq_start(struct rpp_module *mod, 68 const struct v4l2_mbus_framefmt *fmt) 69 { 70 u32 bayerpat, selection; 71 72 rpp_module_clrset(mod, ACQ_CTRL_REG, ACQ_CTRL_RPP_MODE_MASK, 73 ACQ_CTRL_RPP_MODE_BAYER); 74 75 rpp_module_write(mod, ACQ_H_OFFS_REG, 0); 76 rpp_module_write(mod, ACQ_V_OFFS_REG, 0); 77 rpp_module_write(mod, ACQ_H_SIZE_REG, fmt->width); 78 rpp_module_write(mod, ACQ_V_SIZE_REG, fmt->height); 79 rpp_module_write(mod, ACQ_OUT_H_OFFS_REG, 0); 80 rpp_module_write(mod, ACQ_OUT_V_OFFS_REG, 0); 81 rpp_module_write(mod, ACQ_OUT_H_SIZE_REG, fmt->width); 82 rpp_module_write(mod, ACQ_OUT_V_SIZE_REG, fmt->height); 83 84 switch (fmt->code) { 85 case MEDIA_BUS_FMT_SBGGR8_1X8: 86 case MEDIA_BUS_FMT_SBGGR10_1X10: 87 case MEDIA_BUS_FMT_SBGGR12_1X12: 88 mod->info.acq.raw_pattern = RPP_BGGR; 89 bayerpat = ACQ_PROP_BAYER_PAT_BGBG; 90 break; 91 case MEDIA_BUS_FMT_SGBRG8_1X8: 92 case MEDIA_BUS_FMT_SGBRG10_1X10: 93 case MEDIA_BUS_FMT_SGBRG12_1X12: 94 mod->info.acq.raw_pattern = RPP_GBRG; 95 bayerpat = ACQ_PROP_BAYER_PAT_GBGB; 96 break; 97 case MEDIA_BUS_FMT_SGRBG8_1X8: 98 case MEDIA_BUS_FMT_SGRBG10_1X10: 99 case MEDIA_BUS_FMT_SGRBG12_1X12: 100 mod->info.acq.raw_pattern = RPP_GRBG; 101 bayerpat = ACQ_PROP_BAYER_PAT_GRGR; 102 break; 103 case MEDIA_BUS_FMT_SRGGB8_1X8: 104 case MEDIA_BUS_FMT_SRGGB10_1X10: 105 case MEDIA_BUS_FMT_SRGGB12_1X12: 106 mod->info.acq.raw_pattern = RPP_RGGB; 107 bayerpat = ACQ_PROP_BAYER_PAT_RGRG; 108 break; 109 default: 110 return -EINVAL; 111 } 112 113 switch (fmt->code) { 114 case MEDIA_BUS_FMT_SBGGR8_1X8: 115 case MEDIA_BUS_FMT_SGBRG8_1X8: 116 case MEDIA_BUS_FMT_SGRBG8_1X8: 117 case MEDIA_BUS_FMT_SRGGB8_1X8: 118 selection = ACQ_PROP_INPUT_SELECTION_8BIT; 119 break; 120 case MEDIA_BUS_FMT_SBGGR10_1X10: 121 case MEDIA_BUS_FMT_SGBRG10_1X10: 122 case MEDIA_BUS_FMT_SGRBG10_1X10: 123 case MEDIA_BUS_FMT_SRGGB10_1X10: 124 selection = ACQ_PROP_INPUT_SELECTION_10BIT; 125 break; 126 case MEDIA_BUS_FMT_SBGGR12_1X12: 127 case MEDIA_BUS_FMT_SGBRG12_1X12: 128 case MEDIA_BUS_FMT_SGRBG12_1X12: 129 case MEDIA_BUS_FMT_SRGGB12_1X12: 130 selection = ACQ_PROP_INPUT_SELECTION_12BIT; 131 break; 132 default: 133 return -EINVAL; 134 } 135 136 rpp_module_write(mod, ACQ_PROP_REG, bayerpat | selection | 137 ACQ_PROP_SENSOR_IN_LSB_ALIGNED_IN_LSB); 138 139 rpp_module_clrset(mod, ACQ_CTRL_REG, ACQ_CTRL_INFORM_EN_ENABLE, 140 ACQ_CTRL_INFORM_EN_ENABLE); 141 142 return 0; 143 } 144 145 const struct rpp_module_ops rppx1_acq_ops = { 146 .probe = rppx1_acq_probe, 147 .start = rppx1_acq_start, 148 }; 149