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 * Support library for Dreamchip HDR RPPX1 High Dynamic Range Real-time Pixel 8 * Processor. 9 */ 10 11 #include <linux/io.h> 12 #include <linux/module.h> 13 #include <linux/slab.h> 14 15 #include "rppx1.h" 16 17 /* RPP_HDR Base Addresses */ 18 #define RPPX1_HDRREGS_BASE 0x0000 19 #define RPPX1_HDR_IRQ_BASE 0x0200 20 #define RPPX1_RPP_OUT_BASE 0x0800 21 #define RPPX1_RPP_RMAP_BASE 0x0c00 22 #define RPPX1_RPP_RMAP_MEAS_BASE 0x1000 23 #define RPPX1_RPP_MAIN_PRE1_BASE 0x2000 24 #define RPPX1_RPP_MAIN_PRE2_BASE 0x4000 25 #define RPPX1_RPP_MAIN_POST_BASE 0xa000 26 #define RPPX1_RPP_MVOUT_BASE 0xc000 27 #define RPPX1_RPP_FUSA_BASE 0xf000 28 29 #define RPPX1_RPP_HDRREGS_VERSION_REG (RPPX1_HDRREGS_BASE + 0x0000) 30 31 #define RPPX1_RPP_HDR_UPD_REG (RPPX1_HDRREGS_BASE + 0x0004) 32 #define RPPX1_RPP_HDR_UPD_REGS_GEN_CFG_UPD BIT(1) 33 #define RPPX1_RPP_HDR_UPD_REGS_CFG_UPD BIT(0) 34 35 #define RPPX1_RESERVED_3_REG (RPPX1_HDRREGS_BASE + 0x0008) 36 37 #define RPPX1_RPP_HDR_INFORM_ENABLE_REG (RPPX1_HDRREGS_BASE + 0x000c) 38 #define RPPX1_RPP_HDR_INFORM_ENABLE_ENABLE 1 39 #define RPPX1_RPP_HDR_INFORM_ENABLE_DISABLE 0 40 41 #define RPPX1_RPP_HDR_OUT_IF_ON_REG (RPPX1_HDRREGS_BASE + 0x0010) 42 #define RPPX1_RPP_HDR_OUT_IF_OFF_REG (RPPX1_HDRREGS_BASE + 0x0014) 43 44 #define RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_REG (RPPX1_HDRREGS_BASE + 0x0018) 45 #define RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_ENABLE 1 46 #define RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_DISABLE 0 47 48 #define RPPX1_RPP_ISM (RPPX1_HDR_IRQ_BASE + 0x00) 49 #define RPPX1_RPP_RIS (RPPX1_HDR_IRQ_BASE + 0x04) 50 #define RPPX1_RPP_MIS (RPPX1_HDR_IRQ_BASE + 0x08) 51 #define RPPX1_RPP_ISC (RPPX1_HDR_IRQ_BASE + 0x0c) 52 53 /* RPP_OUT/MV_OUT Pipelines - Base Addresses */ 54 #define RPPX1_GAMMA_OUT_BASE 0x0000 /* HV, MV */ 55 #define RPPX1_IS_BASE 0x00c0 /* HV, MV */ 56 #define RPPX1_CSM_BASE 0x0100 /* HV, MV */ 57 #define RPPX1_OUT_IF_BASE 0x0200 /* HV, MV */ 58 #define RPPX1_RPP_OUTREGS_BASE 0x02c0 /* HV, MV */ 59 #define RPPX1_LUV_BASE 0x0300 /* MV */ 60 61 /* PRE1/PRE2/POST Pipelines - Base Addresses */ 62 #define RPPX1_ACQ_BASE 0x0080 /* PRE1, PRE2 */ 63 #define RPPX1_BLS_BASE 0x0100 /* PRE1, PRE2 */ 64 #define RPPX1_GAMMA_IN_BASE 0x0200 /* PRE1, PRE2 */ 65 #define RPPX1_LSC_BASE 0x0400 /* PRE1, PRE2 */ 66 #define RPPX1_AWB_GAIN_BASE 0x0500 /* PRE1, PRE2, POST */ 67 #define RPPX1_DPCC_BASE 0x0600 /* PRE1, PRE2 */ 68 #define RPPX1_DPF_BASE 0x0700 /* PRE1, PRE2 */ 69 #define RPPX1_FILT_BASE 0x0800 /* POST */ 70 #define RPPX1_CAC_BASE 0x0880 /* POST */ 71 #define RPPX1_CCOR_BASE 0x0900 /* POST */ 72 #define RPPX1_HIST_BASE 0x0a00 /* PRE1, PRE2, POST */ 73 #define RPPX1_HIST256_BASE 0x0b00 /* PRE1 */ 74 #define RPPX1_EXM_BASE 0x0c00 /* PRE1, PRE2 */ 75 #define RPPX1_LTM_BASE 0x1000 /* POST */ 76 #define RPPX1_LTM_MEAS_BASE 0x1200 /* POST */ 77 #define RPPX1_WBMEAS_BASE 0x1700 /* POST */ 78 #define RPPX1_BDRGB_BASE 0x1800 /* POST */ 79 #define RPPX1_SHRP_BASE 0x1a00 /* POST */ 80 81 /* Functional Safety Module Base Addresses */ 82 #define RPPX1_FMU_BASE 0x0100 83 84 #define RPPX1_RPP_HDR_FMU_FSM_REG (RPPX1_RPP_FUSA_BASE + RPPX1_FMU_BASE + 0x00) 85 #define RPPX1_RPP_HDR_FMU_FSM_FSM_IRQM_FAULT BIT(23) 86 #define RPPX1_RPP_HDR_FMU_FSM_PRE2_SIZE_FAULT BIT(20) 87 #define RPPX1_RPP_HDR_FMU_FSM_PRE2_TIME_FAULT BIT(19) 88 #define RPPX1_RPP_HDR_FMU_FSM_PRE1_SIZE_FAULT BIT(18) 89 #define RPPX1_RPP_HDR_FMU_FSM_PRE1_TIME_FAULT BIT(17) 90 #define RPPX1_RPP_HDR_FMU_FSM_SIZE_FAULT BIT(16) 91 #define RPPX1_RPP_HDR_FMU_FSM_TIME_FAULT BIT(15) 92 #define RPPX1_RPP_HDR_FMU_FSM_MV_OUT_SIZE_FAULT BIT(14) 93 #define RPPX1_RPP_HDR_FMU_FSM_MV_OUT_TIME_FAULT BIT(13) 94 #define RPPX1_RPP_HDR_FMU_FSM_HV_OUT_SIZE_FAULT BIT(12) 95 #define RPPX1_RPP_HDR_FMU_FSM_HV_OUT_TIME_FAULT BIT(11) 96 #define RPPX1_RPP_HDR_FMU_FSM_MV_OUT_SIZE_ERR BIT(10) 97 #define RPPX1_RPP_HDR_FMU_FSM_IS_OUT_SIZE_ERR BIT(9) 98 #define RPPX1_RPP_HDR_FMU_FSM_PRE2_FIFO_OVFLW BIT(7) 99 #define RPPX1_RPP_HDR_FMU_FSM_PRE1_FIFO_OVFLW BIT(6) 100 #define RPPX1_RPP_HDR_FMU_FSM_PRE1_INFORM_SIZE BIT(5) 101 #define RPPX1_RPP_HDR_FMU_FSM_PRE1_OUTFORM_SIZE BIT(4) 102 #define RPPX1_RPP_HDR_FMU_FSM_PRE2_INFORM_SIZE BIT(3) 103 #define RPPX1_RPP_HDR_FMU_FSM_PRE2_OUTFORM_SIZE BIT(2) 104 105 #define RPPX1_RPP_HDR_FMU_RFS_REG (RPPX1_RPP_FUSA_BASE + RPPX1_FMU_BASE + 0x04) 106 #define RPPX1_RPP_HDR_FMU_MFS_REG (RPPX1_RPP_FUSA_BASE + RPPX1_FMU_BASE + 0x08) 107 #define RPPX1_RPP_HDR_FMU_FSC_REG (RPPX1_RPP_FUSA_BASE + RPPX1_FMU_BASE + 0x0c) 108 109 void rppx1_write(struct rppx1 *rpp, u32 offset, u32 value) 110 { 111 iowrite32(value, rpp->base + offset); 112 } 113 114 u32 rppx1_read(struct rppx1 *rpp, u32 offset) 115 { 116 return ioread32(rpp->base + offset); 117 } 118 119 bool rppx1_interrupt(struct rppx1 *rpp, u32 *isc) 120 { 121 u32 status, raw, fault; 122 123 fault = rppx1_read(rpp, RPPX1_RPP_HDR_FMU_MFS_REG); 124 if (fault) { 125 dev_err(rpp->dev, "%s: fault 0x%08x\n", __func__, fault); 126 rppx1_write(rpp, RPPX1_RPP_HDR_FMU_FSC_REG, fault); 127 } 128 129 /* Read raw interrupt status. */ 130 raw = rppx1_read(rpp, RPPX1_RPP_RIS); 131 status = rppx1_read(rpp, RPPX1_RPP_MIS); 132 133 /* Propagate the isc status. */ 134 if (isc) 135 *isc = status | raw; 136 137 /* Clear enabled interrupts */ 138 rppx1_write(rpp, RPPX1_RPP_ISC, status); 139 140 return !!(status & RPPX1_IRQ_ID_OUT_FRAME); 141 } 142 EXPORT_SYMBOL_GPL(rppx1_interrupt); 143 144 void rppx1_destroy(struct rppx1 *rpp) 145 { 146 kfree(rpp); 147 } 148 EXPORT_SYMBOL_GPL(rppx1_destroy); 149 150 /* 151 * Allocate the private data structure and verify the hardware is present. 152 */ 153 struct rppx1 *rppx1_create(void __iomem *base, struct device *dev) 154 { 155 struct rppx1 *rpp; 156 u32 reg; 157 158 /* Allocate library structure */ 159 rpp = kzalloc_obj(*rpp); 160 if (!rpp) 161 return NULL; 162 163 rpp->base = base; 164 rpp->dev = dev; 165 166 /* Check communication with RPP and verify it truly is a X1. */ 167 reg = rppx1_read(rpp, RPPX1_RPP_HDRREGS_VERSION_REG); 168 if (reg != 3) { 169 dev_err(rpp->dev, "Unsupported HDR version (%u)\n", reg); 170 rppx1_destroy(rpp); 171 return NULL; 172 } 173 174 /* Probe the PRE1 pipeline. */ 175 if (rpp_module_probe(&rpp->pre1.acq, rpp, &rppx1_acq_ops, 176 RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_ACQ_BASE) || 177 rpp_module_probe(&rpp->pre1.bls, rpp, &rppx1_bls_ops, 178 RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_BLS_BASE) || 179 rpp_module_probe(&rpp->pre1.lin, rpp, &rppx1_lin_ops, 180 RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_GAMMA_IN_BASE) || 181 rpp_module_probe(&rpp->pre1.lsc, rpp, &rppx1_lsc_ops, 182 RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_LSC_BASE) || 183 rpp_module_probe(&rpp->pre1.awbg, rpp, &rppx1_awbg_ops, 184 RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_AWB_GAIN_BASE) || 185 rpp_module_probe(&rpp->pre1.dpcc, rpp, &rppx1_dpcc_ops, 186 RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_DPCC_BASE) || 187 rpp_module_probe(&rpp->pre1.bd, rpp, &rppx1_bd_ops, 188 RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_DPF_BASE) || 189 rpp_module_probe(&rpp->pre1.hist, rpp, &rppx1_hist_ops, 190 RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_HIST_BASE) || 191 rpp_module_probe(&rpp->pre1.hist256, rpp, &rppx1_hist256_ops, 192 RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_HIST256_BASE) || 193 rpp_module_probe(&rpp->pre1.exm, rpp, &rppx1_exm_ops, 194 RPPX1_RPP_MAIN_PRE1_BASE + RPPX1_EXM_BASE)) 195 goto err; 196 197 /* Probe the PRE2 pipeline. */ 198 if (rpp_module_probe(&rpp->pre2.acq, rpp, &rppx1_acq_ops, 199 RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_ACQ_BASE) || 200 rpp_module_probe(&rpp->pre2.bls, rpp, &rppx1_bls_ops, 201 RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_BLS_BASE) || 202 rpp_module_probe(&rpp->pre2.lin, rpp, &rppx1_lin_ops, 203 RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_GAMMA_IN_BASE) || 204 rpp_module_probe(&rpp->pre2.lsc, rpp, &rppx1_lsc_ops, 205 RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_LSC_BASE) || 206 rpp_module_probe(&rpp->pre2.awbg, rpp, &rppx1_awbg_ops, 207 RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_AWB_GAIN_BASE) || 208 rpp_module_probe(&rpp->pre2.dpcc, rpp, &rppx1_dpcc_ops, 209 RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_DPCC_BASE) || 210 rpp_module_probe(&rpp->pre2.bd, rpp, &rppx1_bd_ops, 211 RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_DPF_BASE) || 212 rpp_module_probe(&rpp->pre2.hist, rpp, &rppx1_hist_ops, 213 RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_HIST_BASE) || 214 rpp_module_probe(&rpp->pre2.exm, rpp, &rppx1_exm_ops, 215 RPPX1_RPP_MAIN_PRE2_BASE + RPPX1_EXM_BASE)) 216 goto err; 217 218 /* Probe the POST pipeline. */ 219 if (rpp_module_probe(&rpp->post.awbg, rpp, &rppx1_awbg_ops, 220 RPPX1_RPP_MAIN_POST_BASE + RPPX1_AWB_GAIN_BASE) || 221 rpp_module_probe(&rpp->post.ccor, rpp, &rppx1_ccor_ops, 222 RPPX1_RPP_MAIN_POST_BASE + RPPX1_CCOR_BASE) || 223 rpp_module_probe(&rpp->post.hist, rpp, &rppx1_hist_ops, 224 RPPX1_RPP_MAIN_POST_BASE + RPPX1_HIST_BASE) || 225 rpp_module_probe(&rpp->post.db, rpp, &rppx1_db_ops, 226 RPPX1_RPP_MAIN_POST_BASE + RPPX1_FILT_BASE) || 227 rpp_module_probe(&rpp->post.cac, rpp, &rppx1_cac_ops, 228 RPPX1_RPP_MAIN_POST_BASE + RPPX1_CAC_BASE) || 229 rpp_module_probe(&rpp->post.ltm, rpp, &rppx1_ltm_ops, 230 RPPX1_RPP_MAIN_POST_BASE + RPPX1_LTM_BASE) || 231 rpp_module_probe(&rpp->post.ltmmeas, rpp, &rppx1_ltmmeas_ops, 232 RPPX1_RPP_MAIN_POST_BASE + RPPX1_LTM_MEAS_BASE) || 233 rpp_module_probe(&rpp->post.wbmeas, rpp, &rppx1_wbmeas_ops, 234 RPPX1_RPP_MAIN_POST_BASE + RPPX1_WBMEAS_BASE) || 235 rpp_module_probe(&rpp->post.bdrgb, rpp, &rppx1_bdrgb_ops, 236 RPPX1_RPP_MAIN_POST_BASE + RPPX1_BDRGB_BASE) || 237 rpp_module_probe(&rpp->post.shrp, rpp, &rppx1_shrp_ops, 238 RPPX1_RPP_MAIN_POST_BASE + RPPX1_SHRP_BASE)) 239 goto err; 240 241 /* Probe the Human Vision pipeline. */ 242 if (rpp_module_probe(&rpp->hv.ga, rpp, &rppx1_ga_ops, 243 RPPX1_RPP_OUT_BASE + RPPX1_GAMMA_OUT_BASE) || 244 rpp_module_probe(&rpp->hv.is, rpp, &rppx1_is_ops, 245 RPPX1_RPP_OUT_BASE + RPPX1_IS_BASE) || 246 rpp_module_probe(&rpp->hv.ccor, rpp, &rppx1_ccor_csm_ops, 247 RPPX1_RPP_OUT_BASE + RPPX1_CSM_BASE) || 248 rpp_module_probe(&rpp->hv.outif, rpp, &rppx1_outif_ops, 249 RPPX1_RPP_OUT_BASE + RPPX1_OUT_IF_BASE) || 250 rpp_module_probe(&rpp->hv.outregs, rpp, &rppx1_outregs_ops, 251 RPPX1_RPP_OUT_BASE + RPPX1_RPP_OUTREGS_BASE)) 252 goto err; 253 254 /* Probe the Machine Vision pipeline. */ 255 if (rpp_module_probe(&rpp->mv.ga, rpp, &rppx1_ga_ops, 256 RPPX1_RPP_MVOUT_BASE + RPPX1_GAMMA_OUT_BASE) || 257 rpp_module_probe(&rpp->mv.is, rpp, &rppx1_is_ops, 258 RPPX1_RPP_MVOUT_BASE + RPPX1_IS_BASE) || 259 rpp_module_probe(&rpp->mv.ccor, rpp, &rppx1_ccor_csm_ops, 260 RPPX1_RPP_MVOUT_BASE + RPPX1_CSM_BASE) || 261 rpp_module_probe(&rpp->mv.outif, rpp, &rppx1_outif_ops, 262 RPPX1_RPP_MVOUT_BASE + RPPX1_OUT_IF_BASE) || 263 rpp_module_probe(&rpp->mv.outregs, rpp, &rppx1_outregs_ops, 264 RPPX1_RPP_MVOUT_BASE + RPPX1_RPP_OUTREGS_BASE) || 265 rpp_module_probe(&rpp->mv.xyz2luv, rpp, &rppx1_xyz2luv_ops, 266 RPPX1_RPP_MVOUT_BASE + RPPX1_LUV_BASE)) 267 goto err; 268 269 /* Probe the standalone Radiance Mapping modules. */ 270 if (rpp_module_probe(&rpp->rmap, rpp, &rppx1_rmap_ops, 271 RPPX1_RPP_RMAP_BASE) || 272 rpp_module_probe(&rpp->rmapmeas, rpp, &rppx1_rmapmeas_ops, 273 RPPX1_RPP_RMAP_MEAS_BASE)) 274 goto err; 275 276 return rpp; 277 err: 278 rppx1_destroy(rpp); 279 280 return NULL; 281 } 282 EXPORT_SYMBOL_GPL(rppx1_create); 283 284 int rppx1_start(struct rppx1 *rpp, 285 const struct v4l2_mbus_framefmt *input, 286 const struct v4l2_mbus_framefmt *hv, 287 const struct v4l2_mbus_framefmt *mv) 288 { 289 if (rpp_module_call(&rpp->pre1.acq, start, input) || 290 rpp_module_call(&rpp->pre1.bls, start, input) || 291 rpp_module_call(&rpp->pre1.lin, start, input) || 292 rpp_module_call(&rpp->pre1.lsc, start, input) || 293 rpp_module_call(&rpp->pre1.awbg, start, input) || 294 rpp_module_call(&rpp->pre1.dpcc, start, input) || 295 rpp_module_call(&rpp->pre1.bd, start, input) || 296 rpp_module_call(&rpp->pre1.hist, start, input) || 297 rpp_module_call(&rpp->pre1.exm, start, input) || 298 rpp_module_call(&rpp->pre1.hist256, start, input)) 299 return -EINVAL; 300 301 if (rpp_module_call(&rpp->rmap, start, NULL) || 302 rpp_module_call(&rpp->rmapmeas, start, NULL)) 303 return -EINVAL; 304 305 if (rpp_module_call(&rpp->post.awbg, start, input) || 306 rpp_module_call(&rpp->post.db, start, input) || 307 rpp_module_call(&rpp->post.cac, start, input) || 308 rpp_module_call(&rpp->post.ccor, start, input) || 309 rpp_module_call(&rpp->post.ltm, start, input) || 310 rpp_module_call(&rpp->post.bdrgb, start, input) || 311 rpp_module_call(&rpp->post.shrp, start, input) || 312 rpp_module_call(&rpp->post.ltmmeas, start, input) || 313 rpp_module_call(&rpp->post.wbmeas, start, input) || 314 rpp_module_call(&rpp->post.hist, start, input)) 315 return -EINVAL; 316 317 if (hv && (rpp_module_call(&rpp->hv.ga, start, hv) || 318 rpp_module_call(&rpp->hv.ccor, start, hv) || 319 rpp_module_call(&rpp->hv.outregs, start, hv) || 320 rpp_module_call(&rpp->hv.is, start, hv) || 321 rpp_module_call(&rpp->hv.outif, start, hv))) 322 return -EINVAL; 323 324 if (mv && (rpp_module_call(&rpp->mv.ga, start, mv) || 325 rpp_module_call(&rpp->mv.ccor, start, mv) || 326 rpp_module_call(&rpp->mv.xyz2luv, start, mv) || 327 rpp_module_call(&rpp->mv.outregs, start, mv) || 328 rpp_module_call(&rpp->mv.is, start, mv) || 329 rpp_module_call(&rpp->mv.outif, start, mv))) 330 return -EINVAL; 331 332 /* Immediate update for shadows. */ 333 rppx1_write(rpp, RPPX1_RPP_HDR_UPD_REG, RPPX1_RPP_HDR_UPD_REGS_CFG_UPD); 334 335 /* Clear fault interrupts. */ 336 rppx1_write(rpp, RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_REG, 337 RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_ENABLE); 338 rppx1_write(rpp, RPPX1_RPP_HDR_FMU_FSM_REG, 339 RPPX1_RPP_HDR_FMU_FSM_PRE2_FIFO_OVFLW | 340 RPPX1_RPP_HDR_FMU_FSM_PRE1_FIFO_OVFLW); 341 rppx1_write(rpp, RPPX1_RPP_HDR_FMU_FSC_REG, 342 rppx1_read(rpp, RPPX1_RPP_HDR_FMU_MFS_REG)); 343 rppx1_write(rpp, RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_REG, 344 RPPX1_RPP_HDR_SAFETY_ACCESS_PROTECTION_DISABLE); 345 346 /* Set interrupt mask. */ 347 rppx1_write(rpp, RPPX1_RPP_ISM, RPPX1_IRQ_ID_OUT_FRAME); 348 349 /* Immediate commit update for shadows. */ 350 rppx1_write(rpp, RPPX1_RPP_HDR_UPD_REG, RPPX1_RPP_HDR_UPD_REGS_CFG_UPD); 351 352 /* Then for operation update shadows with picture synchronization. */ 353 rppx1_write(rpp, RPPX1_RPP_HDR_UPD_REG, RPPX1_RPP_HDR_UPD_REGS_GEN_CFG_UPD); 354 355 /* Clear any pending interrupts. */ 356 rppx1_interrupt(rpp, NULL); 357 358 /* Enable input formatters. */ 359 rppx1_write(rpp, RPPX1_RPP_HDR_INFORM_ENABLE_REG, 360 RPPX1_RPP_HDR_INFORM_ENABLE_ENABLE); 361 362 return 0; 363 } 364 EXPORT_SYMBOL_GPL(rppx1_start); 365 366 int rppx1_stop(struct rppx1 *rpp) 367 { 368 /* Disable input formatters. */ 369 rppx1_write(rpp, RPPX1_RPP_HDR_INFORM_ENABLE_REG, 370 RPPX1_RPP_HDR_INFORM_ENABLE_DISABLE); 371 372 /* Clear any pending interrupts. */ 373 rppx1_interrupt(rpp, NULL); 374 375 return 0; 376 } 377 EXPORT_SYMBOL_GPL(rppx1_stop); 378 379 MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>"); 380 MODULE_DESCRIPTION("Dreamchip HDR RPPX1 support library"); 381 MODULE_LICENSE("GPL"); 382