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 <media/v4l2-isp.h> 9 #include <media/videobuf2-v4l2.h> 10 11 #include "rppx1.h" 12 13 #define RPPX1_PARAMS_BLOCK_INFO(block, data) \ 14 [RPPX1_PARAMS_BLOCK_TYPE_ ## block] = { \ 15 .size = sizeof(struct rppx1_ ## data ## _params), \ 16 } 17 18 static const struct v4l2_isp_params_block_type_info 19 rppx1_ext_params_blocks_info[] = { 20 RPPX1_PARAMS_BLOCK_INFO(BLS_PRE1, bls), 21 RPPX1_PARAMS_BLOCK_INFO(BLS_PRE2, bls), 22 RPPX1_PARAMS_BLOCK_INFO(LIN_PRE1, lin), 23 RPPX1_PARAMS_BLOCK_INFO(LIN_PRE2, lin), 24 RPPX1_PARAMS_BLOCK_INFO(LSC_PRE1, lsc), 25 RPPX1_PARAMS_BLOCK_INFO(LSC_PRE2, lsc), 26 RPPX1_PARAMS_BLOCK_INFO(AWBG_PRE1, awbg), 27 RPPX1_PARAMS_BLOCK_INFO(AWBG_PRE2, awbg), 28 RPPX1_PARAMS_BLOCK_INFO(CCOR_POST, ccor), 29 RPPX1_PARAMS_BLOCK_INFO(HIST_PRE1, hist), 30 RPPX1_PARAMS_BLOCK_INFO(HIST_PRE2, hist), 31 RPPX1_PARAMS_BLOCK_INFO(HIST_POST, hist), 32 RPPX1_PARAMS_BLOCK_INFO(EXM_PRE1, exm), 33 RPPX1_PARAMS_BLOCK_INFO(EXM_PRE2, exm), 34 RPPX1_PARAMS_BLOCK_INFO(WBMEAS_POST, wbmeas), 35 RPPX1_PARAMS_BLOCK_INFO(GA_HV, ga), 36 RPPX1_PARAMS_BLOCK_INFO(GA_MV, ga), 37 }; 38 39 int rppx1_params(struct rppx1 *rpp, struct vb2_buffer *vb, size_t max_size, 40 rppx1_reg_write write, void *priv) 41 { 42 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 43 struct v4l2_isp_buffer *cfg; 44 size_t block_offset; 45 int ret; 46 47 ret = v4l2_isp_params_validate_buffer_size(rpp->dev, vb, max_size); 48 if (ret) 49 return ret; 50 51 cfg = vb2_plane_vaddr(&vbuf->vb2_buf, 0); 52 53 ret = v4l2_isp_params_validate_buffer(rpp->dev, vb, cfg, 54 rppx1_ext_params_blocks_info, 55 ARRAY_SIZE(rppx1_ext_params_blocks_info)); 56 if (ret) 57 return ret; 58 59 /* Walk the list of parameter blocks and process them. */ 60 block_offset = 0; 61 while (block_offset < cfg->data_size) { 62 const union rppx1_params_block *block = 63 (const union rppx1_params_block *)&cfg->data[block_offset]; 64 struct rpp_module *module; 65 int ret; 66 67 block_offset += block->header.size; 68 69 switch (block->header.type) { 70 case RPPX1_PARAMS_BLOCK_TYPE_BLS_PRE1: 71 module = &rpp->pre1.bls; 72 break; 73 case RPPX1_PARAMS_BLOCK_TYPE_LIN_PRE1: 74 module = &rpp->pre1.lin; 75 break; 76 case RPPX1_PARAMS_BLOCK_TYPE_LSC_PRE1: 77 module = &rpp->pre1.lsc; 78 break; 79 case RPPX1_PARAMS_BLOCK_TYPE_AWBG_PRE1: 80 module = &rpp->pre1.awbg; 81 break; 82 case RPPX1_PARAMS_BLOCK_TYPE_CCOR_POST: 83 module = &rpp->post.ccor; 84 break; 85 case RPPX1_PARAMS_BLOCK_TYPE_HIST_POST: 86 module = &rpp->post.hist; 87 break; 88 case RPPX1_PARAMS_BLOCK_TYPE_EXM_PRE1: 89 module = &rpp->pre1.exm; 90 break; 91 case RPPX1_PARAMS_BLOCK_TYPE_WBMEAS_POST: 92 module = &rpp->post.wbmeas; 93 break; 94 case RPPX1_PARAMS_BLOCK_TYPE_GA_HV: 95 module = &rpp->hv.ga; 96 break; 97 default: 98 dev_warn(rpp->dev, 99 "Not handled RPPX1 block type: 0x%04x\n", 100 block->header.type); 101 continue; 102 } 103 104 ret = rpp_module_call(module, fill_params, block, write, priv); 105 if (ret) { 106 dev_err(rpp->dev, 107 "Error processing RPPX1 block type: 0x%04x\n", 108 block->header.type); 109 return ret; 110 } 111 } 112 113 return 0; 114 } 115 EXPORT_SYMBOL_GPL(rppx1_params); 116