more dependencies resolved

This commit is contained in:
Markus Fröschle
2013-12-29 08:58:58 +00:00
parent cc48a7be12
commit c4772fa216
11 changed files with 191 additions and 249 deletions

View File

@@ -83,6 +83,8 @@ SECTIONS
OBJDIR/videl.o OBJDIR/videl.o
OBJDIR/fbmem.o OBJDIR/fbmem.o
OBJDIR/biosemu.o
OBJDIR/radeon_base.o OBJDIR/radeon_base.o
OBJDIR/radeon_accel.o OBJDIR/radeon_accel.o
OBJDIR/radeon_cursor.o OBJDIR/radeon_cursor.o

View File

@@ -28,6 +28,7 @@
extern int strncmp(const char *s1, const char *s2, size_t max); extern int strncmp(const char *s1, const char *s2, size_t max);
extern char *strcpy(char *dst, const char *src); extern char *strcpy(char *dst, const char *src);
char *strncpy(char *dst, const char *src, size_t max); char *strncpy(char *dst, const char *src, size_t max);
extern int strcmp(const char *s1, const char *s2);
extern size_t strlen(const char *str); extern size_t strlen(const char *str);
extern char *strcat(char *dst, const char *src); extern char *strcat(char *dst, const char *src);
extern char *strncat(char *dst, const char *src, size_t max); extern char *strncat(char *dst, const char *src, size_t max);

View File

@@ -468,7 +468,7 @@ struct fb_info {
extern int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var); extern int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var);
extern int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var); extern int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var);
extern int fb_blank(struct fb_info *info, int blank); extern int fb_blank(struct fb_info *info, int blank);
extern int fb_ioctl(unsigned int cmd, unsigned long arg); extern int fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
extern struct fb_info *framebuffer_alloc(unsigned long size); extern struct fb_info *framebuffer_alloc(unsigned long size);
extern void framebuffer_release(struct fb_info *info); extern void framebuffer_release(struct fb_info *info);

View File

@@ -9,6 +9,7 @@
#include "i2c.h" #include "i2c.h"
#include "i2c-algo-bit.h" #include "i2c-algo-bit.h"
#include "util.h" /* for swpX() */ #include "util.h" /* for swpX() */
#include "wait.h"
//#include "radeon_theatre.h" //#include "radeon_theatre.h"
#include "radeon_reg.h" #include "radeon_reg.h"
@@ -470,7 +471,7 @@ struct radeonfb_info
*/ */
static inline void _radeon_msleep(struct radeonfb_info *rinfo, uint32_t ms) static inline void _radeon_msleep(struct radeonfb_info *rinfo, uint32_t ms)
{ {
mdelay(ms); wait_ms(ms);
} }
#define radeon_msleep(ms) _radeon_msleep(rinfo,ms) #define radeon_msleep(ms) _radeon_msleep(rinfo,ms)

View File

@@ -41,6 +41,7 @@ typedef bool (*checker_func)(void);
extern __inline__ void wait(uint32_t) __attribute__((always_inline)); extern __inline__ void wait(uint32_t) __attribute__((always_inline));
extern __inline__ bool waitfor(uint32_t us, checker_func condition) __attribute__((always_inline)); extern __inline__ bool waitfor(uint32_t us, checker_func condition) __attribute__((always_inline));
/* /*
* wait for the specified number of us on slice timer 0. Replaces the original routines that had * wait for the specified number of us on slice timer 0. Replaces the original routines that had
* the number of useconds to wait for hardcoded in their name. * the number of useconds to wait for hardcoded in their name.
@@ -52,6 +53,13 @@ extern __inline__ void wait(uint32_t us)
while (MCF_SLT_SCNT(0) - target > 0); while (MCF_SLT_SCNT(0) - target > 0);
} }
/*
* same as above, but with milliseconds wait time
*/
extern __inline__ void wait_ms(uint32_t ms)
{
wait(ms * 1000);
}
/* /*
* the same as above, with a checker function which gets called while * the same as above, with a checker function which gets called while
* busy waiting and allows for an early return if it returns true * busy waiting and allows for an early return if it returns true

View File

@@ -321,6 +321,7 @@ extern "C" { /* Use "C" linkage when in C++ mode */
*/ */
extern X86EMU_sysEnv _X86EMU_env; extern X86EMU_sysEnv _X86EMU_env;
#define M _X86EMU_env #define M _X86EMU_env
#define X86_EAX M.x86.R_EAX #define X86_EAX M.x86.R_EAX

View File

@@ -57,6 +57,7 @@
#include "radeonfb.h" #include "radeonfb.h"
#include "edid.h" #include "edid.h"
#include "ati_ids.h" #include "ati_ids.h"
#include "driver_mem.h"
#include "bas_printf.h" #include "bas_printf.h"
#include "exceptions.h" /* for set_ipl() */ #include "exceptions.h" /* for set_ipl() */
@@ -68,8 +69,6 @@
#endif /* DBG_RADEON */ #endif /* DBG_RADEON */
extern void run_bios(struct radeonfb_info *rinfo); extern void run_bios(struct radeonfb_info *rinfo);
extern void mdelay(int32_t msec);
extern void udelay(int32_t usec);
#define MAX_MAPPED_VRAM (2048*2048*4) #define MAX_MAPPED_VRAM (2048*2048*4)
#define MIN_MAPPED_VRAM (1024*768*4) #define MIN_MAPPED_VRAM (1024*768*4)
@@ -1011,7 +1010,7 @@ int32_t radeon_screen_blank(struct radeonfb_info *rinfo, int32_t blank, int32_t
OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb); OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);
val &= ~(LVDS_BL_MOD_EN); val &= ~(LVDS_BL_MOD_EN);
OUTREG(LVDS_GEN_CNTL, val); OUTREG(LVDS_GEN_CNTL, val);
udelay(100); wait(100);
val &= ~(LVDS_ON | LVDS_EN); val &= ~(LVDS_ON | LVDS_EN);
OUTREG(LVDS_GEN_CNTL, val); OUTREG(LVDS_GEN_CNTL, val);
val &= ~LVDS_DIGON; val &= ~LVDS_DIGON;
@@ -1525,7 +1524,7 @@ int radeonfb_set_par(struct fb_info *info)
int depth = var_to_depth(mode); int depth = var_to_depth(mode);
int use_rmx = 0; int use_rmx = 0;
newmode = (struct radeon_regs *)Funcs_malloc(sizeof(struct radeon_regs),3); newmode = (struct radeon_regs *) driver_mem_alloc(sizeof(struct radeon_regs));
if (!newmode) if (!newmode)
return -1; //-ENOMEM; return -1; //-ENOMEM;
/* We always want engine to be idle on a mode switch, even /* We always want engine to be idle on a mode switch, even
@@ -1774,7 +1773,7 @@ int radeonfb_set_par(struct fb_info *info)
/* Update fix */ /* Update fix */
info->fix.line_length = rinfo->pitch*64; info->fix.line_length = rinfo->pitch*64;
info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
Funcs_free(newmode); driver_mem_free(newmode);
return 0; return 0;
} }
@@ -2186,9 +2185,9 @@ void radeonfb_pci_unregister(void)
// radeonfb_pm_exit(rinfo); // radeonfb_pm_exit(rinfo);
uninstall_vbl_timer(radeon_timer_func); uninstall_vbl_timer(radeon_timer_func);
if (rinfo->mon1_EDID!=NULL) if (rinfo->mon1_EDID!=NULL)
Funcs_free(rinfo->mon1_EDID); driver_mem_free(rinfo->mon1_EDID);
if (rinfo->mon2_EDID!=NULL) if (rinfo->mon2_EDID!=NULL)
Funcs_free(rinfo->mon2_EDID); driver_mem_free(rinfo->mon2_EDID);
if (rinfo->mon1_modedb) if (rinfo->mon1_modedb)
fb_destroy_modedb(rinfo->mon1_modedb); fb_destroy_modedb(rinfo->mon1_modedb);
#ifdef CONFIG_FB_RADEON_I2C #ifdef CONFIG_FB_RADEON_I2C

View File

@@ -1,5 +1,8 @@
#include "radeonfb.h" #include "radeonfb.h"
#include "wait.h"
#include "edid.h" #include "edid.h"
#include "driver_mem.h"
#include "bas_string.h"
#define DBG_MONITOR #define DBG_MONITOR
#ifdef DBG_MONITOR #ifdef DBG_MONITOR
@@ -104,7 +107,7 @@ static int radeon_crt_is_connected(struct radeonfb_info *rinfo, int is_crt_dac)
ulData &= ~(DAC_RANGE_CNTL_MASK | DAC_PDWN); ulData &= ~(DAC_RANGE_CNTL_MASK | DAC_PDWN);
ulData |= 0x2; ulData |= 0x2;
OUTREG(DAC_CNTL, ulData); OUTREG(DAC_CNTL, ulData);
mdelay(1); wait_ms(1);
ulData = INREG(DAC_CNTL); ulData = INREG(DAC_CNTL);
connected = (DAC_CMP_OUTPUT & ulData) ? 1 : 0; connected = (DAC_CMP_OUTPUT & ulData) ? 1 : 0;
ulData = ulOrigVCLK_ECP_CNTL; ulData = ulOrigVCLK_ECP_CNTL;
@@ -160,17 +163,17 @@ static int radeon_parse_monitor_layout(struct radeonfb_info *rinfo, const char *
s1[i] = '\0'; s1[i] = '\0';
s2[0] = '\0'; s2[0] = '\0';
} }
if(Funcs_equal(s1, "CRT")) if (strcmp(s1, "CRT"))
rinfo->mon1_type = MT_CRT; rinfo->mon1_type = MT_CRT;
else if(Funcs_equal(s1, "TMDS")) else if (strcmp(s1, "TMDS"))
rinfo->mon1_type = MT_DFP; rinfo->mon1_type = MT_DFP;
else if(Funcs_equal(s1, "LVDS")) else if (strcmp(s1, "LVDS"))
rinfo->mon1_type = MT_LCD; rinfo->mon1_type = MT_LCD;
if(Funcs_equal(s2, "CRT")) if (strcmp(s2, "CRT"))
rinfo->mon2_type = MT_CRT; rinfo->mon2_type = MT_CRT;
else if(Funcs_equal(s2, "TMDS")) else if (strcmp(s2, "TMDS"))
rinfo->mon2_type = MT_DFP; rinfo->mon2_type = MT_DFP;
else if(Funcs_equal(s2, "LVDS")) else if (strcmp(s2, "LVDS"))
rinfo->mon2_type = MT_LCD; rinfo->mon2_type = MT_LCD;
return 1; return 1;
} }
@@ -358,9 +361,9 @@ void radeon_probe_screens(struct radeonfb_info *rinfo,
} }
if (ignore_edid) if (ignore_edid)
{ {
Funcs_free(rinfo->mon1_EDID); driver_mem_free(rinfo->mon1_EDID);
rinfo->mon1_EDID = NULL; rinfo->mon1_EDID = NULL;
Funcs_free(rinfo->mon2_EDID); driver_mem_free(rinfo->mon2_EDID);
rinfo->mon2_EDID = NULL; rinfo->mon2_EDID = NULL;
} }
bail: bail:

View File

@@ -68,6 +68,19 @@ int memcmp(const char *s1, const char *s2, size_t max)
return cmp; return cmp;
} }
int strcmp(const char *s1, const char *s2)
{
int i;
int cmp;
for (i = 0; *s1++ && *s2++; i++)
{
cmp * (*s1 - *s2);
if (cmp != 0) return cmp;
}
return cmp;
}
int strncmp(const char *s1, const char *s2, size_t max) int strncmp(const char *s1, const char *s2, size_t max)
{ {
int i; int i;

View File

@@ -11,9 +11,19 @@
* for more details. * for more details.
*/ */
#include <bas_string.h> #include "bas_types.h"
#include "bas_printf.h"
#include "bas_string.h"
#include "fb.h" #include "fb.h"
#include "radeonfb.h" #include "radeonfb.h"
#include "driver_mem.h"
#define DBG_FBMEM
#ifdef DBG_FBMEM
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else
#define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_FBMEM */
long mem_cmp(char *p1, char *p2, long size) long mem_cmp(char *p1, char *p2, long size)
{ {
@@ -75,19 +85,19 @@ int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
int fb_blank(struct fb_info *info, int blank) int fb_blank(struct fb_info *info, int blank)
{ {
// DPRINT("fb_blank\r\n"); dbg("fb_blank\r\n");
if (blank > FB_BLANK_POWERDOWN) if (blank > FB_BLANK_POWERDOWN)
blank = FB_BLANK_POWERDOWN; blank = FB_BLANK_POWERDOWN;
return(info->fbops->fb_blank(blank, info)); return(info->fbops->fb_blank(blank, info));
} }
int fb_ioctl(unsigned int cmd, unsigned long arg) int fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{ {
struct fb_info *info = info_fvdi;
struct fb_var_screeninfo var; struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix; struct fb_fix_screeninfo fix;
void *argp = (void *) arg; void *argp = (void *) arg;
int i; int i;
switch(cmd) switch(cmd)
{ {
case FBIOGET_VSCREENINFO: case FBIOGET_VSCREENINFO:
@@ -123,10 +133,6 @@ int fb_ioctl(unsigned int cmd, unsigned long arg)
} }
#if 1
static struct radeonfb_info struct_radeon_info;
/** /**
* framebuffer_alloc - creates a new frame buffer info structure * framebuffer_alloc - creates a new frame buffer info structure
* *
@@ -142,25 +148,24 @@ static struct radeonfb_info struct_radeon_info;
*/ */
struct fb_info *framebuffer_alloc(unsigned long size) struct fb_info *framebuffer_alloc(unsigned long size)
{ {
static struct fb_info struct_info; struct fb_info *info = driver_mem_alloc(sizeof(struct fb_info));
struct fb_info *info = &struct_info;
if (info == NULL)
{
dbg("%s: could not allocate fb_info structure\r\n", __FUNCTION__);
return 0;
}
memset(info, 0, sizeof(struct fb_info)); memset(info, 0, sizeof(struct fb_info));
if (size) if (size)
{ {
if(size <= sizeof(struct radeonfb_info)) char *p = driver_mem_alloc(size);
{
memset(&struct_radeon_info, 0, sizeof(struct radeonfb_info));
info->par = (void *)&struct_radeon_info;
}
else
{
char *p = Funcs_malloc(size, 3);
if (!p) if (!p)
return NULL; return NULL;
memset(p, 0, size); memset(p, 0, size);
info->par = p; info->par = p;
} }
}
return info; return info;
} }
@@ -175,59 +180,6 @@ struct fb_info *framebuffer_alloc(unsigned long size)
*/ */
void framebuffer_release(struct fb_info *info) void framebuffer_release(struct fb_info *info)
{ {
if(info->par != (void *)&struct_radeon_info) driver_mem_free(info->par);
Funcs_free(info->par);
} }
#else
/**
* framebuffer_alloc - creates a new frame buffer info structure
*
* @size: size of driver private data, can be zero
* @dev: pointer to the device for this fb, this can be NULL
*
* Creates a new frame buffer info structure. Also reserves @size bytes
* for driver private data (info->par). info->par (if any) will be
* aligned to sizeof(long).
*
* Returns the new structure, or NULL if an error occured.
*
*/
struct fb_info *framebuffer_alloc(unsigned long size)
{
#define BYTES_PER_LONG (32/8)
#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
int fb_info_size = sizeof(struct fb_info);
struct fb_info *info;
char *p;
if(size)
fb_info_size += PADDING;
p = Funcs_malloc(fb_info_size + size, 3);
if(!p)
return NULL;
memset(p, 0, fb_info_size + size);
info = (struct fb_info *) p;
if(size)
info->par = p + fb_info_size;
return info;
#undef PADDING
#undef BYTES_PER_LONG
}
/**
* framebuffer_release - marks the structure available for freeing
*
* @info: frame buffer info structure
*
* Drop the reference count of the class_device embedded in the
* framebuffer info structure.
*
*/
void framebuffer_release(struct fb_info *info)
{
Funcs_free(info);
}
#endif

View File

@@ -1,11 +1,20 @@
#define RINFO_ONLY #define RINFO_ONLY
#include "radeonfb.h" #include "radeonfb.h"
#include "bas_printf.h"
#include "bas_string.h" #include "bas_string.h"
#include "util.h"
#include "x86emu.h" #include "x86emu.h"
#include "pci.h" #include "pci.h"
#include "pci_ids.h" #include "pci_ids.h"
// #include "vgatables.h" // #include "vgatables.h"
#define DBG_EMULATOR
#ifdef DBG_EMULATOR
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else
#define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_EMULATOR */
#define USE_SDRAM #define USE_SDRAM
#define DIRECT_ACCESS #define DIRECT_ACCESS
@@ -22,11 +31,6 @@
#define SYS_BIOS 0xF0000 #define SYS_BIOS 0xF0000
#define SIZE_EMU 0x100000 #define SIZE_EMU 0x100000
#ifdef DIRECT_ACCESS
extern uint16_t swpw(uint16_t val);
extern uint32_t swap_long(uint32_t val);
#endif
typedef struct typedef struct
{ {
long ident; long ident;
@@ -105,15 +109,10 @@ static uint8_t inb(uint16_t port)
if ((port >= offset_port) && (port <= offset_port + 0xFF)) if ((port >= offset_port) && (port <= offset_port + 0xFF))
{ {
#ifdef DEBUG_X86EMU_PCI dbg("inb(");
DPRINTVALHEX("inb(", port);
#endif
val = *(uint8_t *)(offset_io+(uint32_t)port); val = *(uint8_t *)(offset_io+(uint32_t)port);
#ifdef DEBUG_X86EMU_PCI dbg("0x%x) = 0x%x\r\n", port, val);
DPRINTVALHEX(") = ", val);
DPRINT("\r\n");
#endif
} }
return val; return val;
} }
@@ -124,14 +123,9 @@ static uint16_t inw(uint16_t port)
if ((port >= offset_port) && (port <= offset_port+0xFF)) if ((port >= offset_port) && (port <= offset_port+0xFF))
{ {
#ifdef DEBUG_X86EMU_PCI dbg("inw(");
DPRINTVALHEX("inw(", port);
#endif
val = swpw(*(uint16_t *)(offset_io+(uint32_t)port)); val = swpw(*(uint16_t *)(offset_io+(uint32_t)port));
#ifdef DEBUG_X86EMU_PCI dbg("0x%x) = 0x%x\r\n", port, val);
DPRINTVALHEX(") = ", val);
DPRINT("\r\n");
#endif
} }
return val; return val;
} }
@@ -141,23 +135,15 @@ static uint32_t inl(uint16_t port)
uint32_t val = 0; uint32_t val = 0;
if ((port >= offset_port) && (port <= offset_port+0xFF)) if ((port >= offset_port) && (port <= offset_port+0xFF))
{ {
#ifdef DEBUG_X86EMU_PCI dbg("inl(");
DPRINTVALHEX("inl(", port);
#endif
val = swpl(*(uint32_t *)(offset_io+(uint32_t)port)); val = swpl(*(uint32_t *)(offset_io+(uint32_t)port));
#ifdef DEBUG_X86EMU_PCI dbg("0x%x) = 0x%x\r\n", port, val);
DPRINTVALHEX(") = ", val);
DPRINT("\r\n");
#endif
} }
else if (port == 0xCF8) else if (port == 0xCF8)
{ {
dbg("inl(");
val = config_address_reg; val = config_address_reg;
#ifdef DEBUG_X86EMU_PCI dbg("0x%x) = 0x%x\r\n", port, val);
DPRINTVALHEX("inl(", port);
DPRINTVALHEX(") = ", val);
DPRINT("\r\n");
#endif
} }
else if ((port == 0xCFC) && ((config_address_reg & 0x80000000) != 0)) else if ((port == 0xCFC) && ((config_address_reg & 0x80000000) != 0))
{ {
@@ -173,11 +159,7 @@ static uint32_t inl(uint16_t port)
val = pci_read_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC); val = pci_read_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC);
break; break;
} }
#ifdef DEBUG_X86EMU_PCI dbg("inl(0x%x) = 0x%x\r\n", port, val);
DPRINTVALHEX("inl(", port);
DPRINTVALHEX(") = ", val);
DPRINT("\r\n");
#endif
} }
return val; return val;
} }
@@ -186,11 +168,7 @@ void outb(uint8_t val, uint16_t port)
{ {
if ((port >= offset_port) && (port <= offset_port + 0xFF)) if ((port >= offset_port) && (port <= offset_port + 0xFF))
{ {
#ifdef DEBUG_X86EMU_PCI dbg("outb(0x%x, 0x%x)\r\n", port, val);
DPRINTVALHEX("outb(", port);
DPRINTVALHEX(") = ", val);
DPRINT("\r\n");
#endif
*(uint8_t *)(offset_io + (uint32_t) port) = val; *(uint8_t *)(offset_io + (uint32_t) port) = val;
} }
} }
@@ -199,11 +177,7 @@ void outw(uint16_t val, uint16_t port)
{ {
if ((port >= offset_port) && (port <= offset_port + 0xFF)) if ((port >= offset_port) && (port <= offset_port + 0xFF))
{ {
#ifdef DEBUG_X86EMU_PCI dbg("outw(0x%x, 0x%x)\r\n", port, val);
DPRINTVALHEX("outw(", port);
DPRINTVALHEX(") = ", val);
DPRINT("\r\n");
#endif
*(uint16_t *)(offset_io + (uint32_t) port) = swpw(val); *(uint16_t *)(offset_io + (uint32_t) port) = swpw(val);
} }
} }
@@ -212,20 +186,12 @@ void outl(uint32_t val, uint16_t port)
{ {
if ((port >= offset_port) && (port <= offset_port + 0xFF)) if ((port >= offset_port) && (port <= offset_port + 0xFF))
{ {
#ifdef DEBUG_X86EMU_PCI dbg("outl(0x%x, 0x%x)\r\n", port, val);
DPRINTVALHEX("outl(", port);
DPRINTVALHEX(") = ", val);
DPRINT("\r\n");
#endif
*(uint32_t *)(offset_io + (uint32_t) port) = swpl(val); *(uint32_t *)(offset_io + (uint32_t) port) = swpl(val);
} }
else if (port == 0xCF8) else if (port == 0xCF8)
{ {
#ifdef DEBUG_X86EMU_PCI dbg("outl(0x%x, 0x%x)\r\n", port, val);
DPRINTVALHEX("outl(", port);
DPRINTVALHEX(") = ", val);
DPRINT("\r\n");
#endif
config_address_reg = val; config_address_reg = val;
} }
else if ((port == 0xCFC) && ((config_address_reg & 0x80000000) !=0)) else if ((port == 0xCFC) && ((config_address_reg & 0x80000000) !=0))
@@ -234,11 +200,7 @@ void outl(uint32_t val, uint16_t port)
offset_port = (uint16_t)val & 0xFFFC; offset_port = (uint16_t)val & 0xFFFC;
else else
{ {
#ifdef DEBUG_X86EMU_PCI dbg("outl(0x%x, 0x%x)\r\n", port, val);
DPRINTVALHEX("outl(", port);
DPRINTVALHEX(") = ", val);
DPRINT("\r\n");
#endif
pci_write_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC, val); pci_write_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC, val);
} }
} }