Started to write a generic register overriding interface. Goals:
- to be used for other features as well: FPS override, crop_rec (for now)
- allow any modules or core features to override any registers (ADTG, CMOS, ENGIO, DFE, whatever else we'll find in the future)
- allow more than one module to override the same registers without "fighting", e.g.:
- if dual_iso changes CMOS[0], the ISO tweaks module should be able to override CMOS[7], for example [easy]
- if dual_iso changes CMOS[0] and the ISO tweaks module decides to use some custom gains in CMOS[0], that should work as well
- FPS override and crop_rec should work well together (for some definition of "well"... TBD)
- allow custom overriding logic
- do that fast (LiveView doesn't like slow overrides; searching in a big list for every single ADTG or ENGIO register is likely overkill)
- minimally invasive (install/uninstall the hooks only when actually used)
- compatible with old and new models (DIGIC 4 and 5 for now, keeping in mind DIGIC 2, 3, 6, 7 and 8 )
Initial draft, for review:
/* Register overrides */
/* Core APIs for overriding various registers:
* - ADTG
* - CMOS
* - DFE
* - ENGIO
* - ...
*/
/* Each register type has an "add" function, which can be used to set up certain overrides,
* and a "del" function, which "uninstalls" previous overrides (identified by what "add" returned).
*
* Optional features: check for expected values or call back some CBR.
*/
/* Each "add" function has the following parameters:
* - register "target" (optional, if there are more chips of the same type, see e.g. ADTG "destination")
* - register address (each register has some unique identifier)
* - register mask (which address bits should be ignored, e.g. to override more than one register)
* - new value (after overriding)
* - expected value (with a boolean flag to enable this check)
* - optional CBR for custom overriding logic (if not NULL, the "new value" is ignored)
* and returns a positive ID if successful, or negative error code if not.
*
* Each "del" function takes one parameter (the ID returned by "add")
* and returns 0 on success, or negative error code on failure.
*/
#ifndef _regs_h_
#define _regs_h_
typedef uint16_t (*adtg_override_func)(
uint8_t dest, /* ADTG chip "destination" (bit field, e.g. 6 will override both ADTG2 and ADTG4) */
uint16_t reg, /* ADTG register ID (0x800C, 0xFE etc) */
uint16_t old_val /* value before overriding */
); /* returns: updated value (or old_val if nothing changes) */
typedef uint16_t (*cmos_override_func)(
uint8_t reg, /* CMOS register ID (0, 1, 2 etc) */
uint16_t old_val /* value before overriding */
); /* returns: updated value (or old_val if nothing changes) */
typedef uint32_t (*engio_override_func)(
uint32_t reg, /* ENGIO register address (0xC0F06014 etc) */
uint32_t old_val /* value before overriding */
); /* returns: updated value (or old_val if nothing changes) */
typedef uint32_t (*dfe_override_func)(
uint16_t reg, /* DFE register address (0x1D02 etc) */
uint16_t old_val /* value before overriding */
); /* returns: updated value (or old_val if nothing changes) */
int regs_ovr_adtg_add(uint8_t dest, uint16_t reg, uint16_t mask,
uint16_t new_val,
adtg_override_func cbr, void * opaque);
int regs_ovr_cmos_add(uint8_t reg, uint8_t mask,
uint16_t new_val, cmos_override_func cbr, void * opaque);
int regs_ovr_engio_add(uint32_t reg, uint32_t mask,
uint32_t new_val, engio_override_func cbr, void * opaque);
int regs_ovr_dfe_add(uint16_t reg, uint16_t mask,
uint16_t new_val, dfe_override_func cbr, void * opaque);
int regs_ovr_adtg_del(int id);
int regs_ovr_cmos_del(int id);
int regs_ovr_engio_del(int id);
int regs_ovr_dfe_del(int id);
/* TODO (if the above will work well enough):
* - TFT SIO registers?
* - HDMI chip registers?
* - Sound registers? (integrate with new-sound-system?)
* - Other peripheral registers?
*/
#endif /* _regs_h_ */