pc8736x_gpio needs a real nsc_gpio_ops.gpio_current(), (the previous just threw a dev_warn). This patch adds that code to read the chip's current-pin-output-settings, then adds the initialization of the shadow-regs to them. (the shadow regs are there to preclude the slow peripheral access needed otherwize) Signed-off-by: Jim Cromie <jim.cromie@xxxxxxxxx> diffstat patch.shadow-current pc8736x_gpio.c | 29 ++++++++++++++++++++++++----- 1 files changed, 24 insertions(+), 5 deletions(-) diff -ruNp -X dontdiff -X exclude-diffs ab-16/drivers/char/pc8736x_gpio.c ab-17/drivers/char/pc8736x_gpio.c --- ab-16/drivers/char/pc8736x_gpio.c 2006-06-02 13:39:15.000000000 -0600 +++ ab-17/drivers/char/pc8736x_gpio.c 2006-06-02 13:40:23.000000000 -0600 @@ -33,7 +33,7 @@ MODULE_PARM_DESC(major, "Major device nu static DEFINE_SPINLOCK(pc8736x_gpio_config_lock); static unsigned pc8736x_gpio_base; -/* static u8 pc8736x_gpio_shadow[4]; */ +static u8 pc8736x_gpio_shadow[4]; #define SIO_BASE1 0x2E /* 1st command-reg to check */ #define SIO_BASE2 0x4E /* alt command-reg to check */ @@ -191,6 +191,7 @@ static void pc8736x_gpio_set(unsigned mi val = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_IN); dev_dbg(&pdev->dev, "wrote %x, read: %x\n", curval, val); + pc8736x_gpio_shadow[port] = val; } static void pc8736x_gpio_set_high(unsigned index) @@ -203,15 +204,18 @@ static void pc8736x_gpio_set_low(unsigne pc8736x_gpio_set(index, 0); } -static int pc8736x_gpio_current(unsigned index) +static int pc8736x_gpio_current(unsigned minor) { - dev_warn(&pdev->dev, "pc8736x_gpio_current unimplemented\n"); - return 0; + int port, bit; + minor &= 0x1f; + port = minor >> 3; + bit = minor & 7; + return pc8736x_gpio_shadow[port] >> bit & 0x01; } static void pc8736x_gpio_change(unsigned index) { - pc8736x_gpio_set(index, !pc8736x_gpio_get(index)); + pc8736x_gpio_set(index, !pc8736x_gpio_current(index)); } extern void nsc_gpio_dump(struct nsc_gpio_ops *amp, unsigned iminor); @@ -247,6 +251,18 @@ static struct file_operations pc8736x_gp .read = nsc_gpio_read, }; +static void __init pc8736x_init_shadow(void) +{ + int port; + + /* read the current values driven on the GPIO signals */ + for (port = 0; port < 4; ++port) + pc8736x_gpio_shadow[port] + = inb_p(pc8736x_gpio_base + port_offset[port] + + PORT_OUT); + +} + static int __init pc8736x_gpio_init(void) { int r, rc; @@ -292,6 +308,7 @@ static int __init pc8736x_gpio_init(void dev_info(&pdev->dev, "GPIO ioport %x reserved\n", pc8736x_gpio_base); + pc8736x_init_shadow(); r = register_chrdev(major, DEVNAME, &pc8736x_gpio_fops); if (r < 0) { @@ -315,5 +332,7 @@ static void __exit pc8736x_gpio_cleanup( unregister_chrdev(major, DEVNAME); } +EXPORT_SYMBOL(pc8736x_access); + module_init(pc8736x_gpio_init); module_exit(pc8736x_gpio_cleanup); -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/