MFD: DA9052 MFD core module v2
Subsystems (2)
PATCH 1/11 MFD: DA9052 MFD core module v2
The DA9052 is a highly integrated PMIC subsystem with supply domain flexibility to support wide range of high performance application.
It provides voltage regulators, GPIO controller, Touch Screen, RTC, Battery control and other functionality.
---
Changes since v2:
- Drop da9052_irqs[] table.
- Move struct da9052_subdev_info[].
- Remove initialization of static member.
- Care for NULL pdata init().
- Check removal of subdevices on errors.
- Remove open source spi code.
- Remove '_spi' from the driver name.
- Move tbat_lookup table from header file.
- Remove irq.h
- Remove num_gpio variable from pdata
--- drivers/mfd/Kconfig | 25 ++ drivers/mfd/Makefile | 7 + drivers/mfd/da9052-core.c | 539 +++++++++++++++++++++++++ drivers/mfd/da9052-i2c.c | 168 ++++++++ drivers/mfd/da9052-irq.c | 168 ++++++++ drivers/mfd/da9052-spi.c | 132 +++++++ include/linux/mfd/da9052/da9052.h | 91 +++++ include/linux/mfd/da9052/pdata.h | 43 ++ include/linux/mfd/da9052/reg.h | 777 +++++++++++++++++++++++++++++++++++++ 9 files changed, 1950 insertions(+), 0 deletions(-) create mode 100755 drivers/mfd/da9052-core.c create mode 100755 drivers/mfd/da9052-i2c.c create mode 100755 drivers/mfd/da9052-irq.c create mode 100755 drivers/mfd/da9052-spi.c create mode 100755 include/linux/mfd/da9052/da9052.h create mode 100755 include/linux/mfd/da9052/pdata.h create mode 100755 include/linux/mfd/da9052/reg.h
drivers/mfd/Kconfig +25 -0
@@ -306,6 +306,31 @@ config PMIC_DA903X individual components like LCD backlight, voltage regulators, LEDs and battery-charger under the corresponding menus. +config PMIC_DA9052 + bool + +config MFD_DA9052_SPI + bool "Support Dialog Semiconductor DA9052 PMIC with SPI" + select MFD_CORE + select PMIC_DA9052 + depends on SPI_MASTER=y + help + Support for the Dialog Semiconductor DA9052 PMIC + when controlled using SPI. This driver provides common support + for accessing the device, additional drivers must be enabled in + order to use the functionality of the device. + +config MFD_DA9052_I2C + bool "Support Dialog Semiconductor DA9052 PMIC with I2C" + select MFD_CORE + select PMIC_DA9052 + depends on I2C=y + help + Support for the Dialog Semiconductor DA9052 PMIC + when controlled using I2C. This driver provides common support + for accessing the device, additional drivers must be enabled in + order to use the functionality of the device. + config PMIC_ADP5520 bool "Analog Devices ADP5520/01 MFD PMIC Core Support" depends on I2C=y
drivers/mfd/Makefile +7 -0
@@ -60,6 +60,13 @@ endif obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o obj-$(CONFIG_PMIC_DA903X) += da903x.o + +da9052-objs := da9052-core.o da9052-irq.o +obj-$(CONFIG_PMIC_DA9052) += da9052.o + +obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o +obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o + max8925-objs := max8925-core.o max8925-i2c.o obj-$(CONFIG_MFD_MAX8925) += max8925.o obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o
drivers/mfd/da9052-core.c new file +539 -0
539 lines not on this page · raw message
drivers/mfd/da9052-i2c.c new file +168 -0
168 lines not on this page · raw message
drivers/mfd/da9052-irq.c new file +168 -0
168 lines not on this page · raw message
drivers/mfd/da9052-spi.c new file +132 -0
132 lines not on this page · raw message
include/linux/mfd/da9052/da9052.h new file +91 -0
91 lines not on this page · raw message
include/linux/mfd/da9052/pdata.h new file +43 -0
43 lines not on this page · raw message
include/linux/mfd/da9052/reg.h new file +777 -0
777 lines not on this page · raw message
Quoted 8 lines · On Tuesday 05 July 2011, ashishj3 wrote:
The DA9052 is a highly integrated PMIC subsystem with supply domain flexibility to support wide range of high performance application.
It provides voltage regulators, GPIO controller, Touch Screen, RTC, Battery control and other functionality.
Signed-off-by David Dajun Chen <[email protected]>Signed-off-by Ashish Jangam <[email protected]>
Quoted 13 lines
-----Original Message-----
From: Arnd Bergmann [mailto:[email protected]]
Sent: Tuesday, July 05, 2011 8:25 PM
To: Ashish Jangam
Cc: Mark Brown; [email protected]; [email protected]; Dajun; [email protected]
Subject: Re: [PATCH 01/11] MFD: DA9052 MFD core module v2Quoted 1 line · On Tuesday 05 July 2011, ashishj3 wrote:
The DA9052 is a highly integrated PMIC subsystem with supply domain
flexibility
Quoted 2 lines
to support wide range of high performance application.
Quoted 7 lines
Quoted 5 lines
It provides voltage regulators, GPIO controller, Touch Screen, RTC, Battery control and other functionality.
Signed-off-by David Dajun Chen <[email protected]>Signed-off-by Ashish Jangam <[email protected]>Reviewed-by Arnd Bergmann <[email protected]>
Can anyone ack this patch?
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
Quoted 5 lines · Ashish Jangam
Quoted 3 lines
-----Original Message-----
From: Arnd Bergmann [mailto:[email protected]]
Sent: Tuesday, July 05, 2011 8:25 PMCan anyone ack this patch?
You've only left it about a week for a response. You cannot demand any particular response from volunteers. In the case of MFD Samuel normally goes through things once a month or so.
Quoted 13 lines · On Monday 11 July 2011 08:57:46 Ashish Jangam wrote:
Quoted 13 lines
-----Original Message-----
From: Arnd Bergmann [mailto:[email protected]]
Sent: Tuesday, July 05, 2011 8:25 PM
To: Ashish Jangam
Cc: Mark Brown; [email protected]; [email protected]; Dajun; [email protected]
Subject: Re: [PATCH 01/11] MFD: DA9052 MFD core module v2Quoted 1 line · On Tuesday 05 July 2011, ashishj3 wrote:
The DA9052 is a highly integrated PMIC subsystem with supply domain
flexibility
Quoted 2 lines
to support wide range of high performance application.
Quoted 8 lines
Quoted 7 lines
Quoted 5 lines
It provides voltage regulators, GPIO controller, Touch Screen, RTC, Battery control and other functionality.
Signed-off-by David Dajun Chen <[email protected]>Signed-off-by Ashish Jangam <[email protected]>Reviewed-by Arnd Bergmann <[email protected]>Can anyone ack this patch?
What do you think my message was? Reviewed-by is usually stronger than Acked-by, it means that I actually had a closer look and am now happy with the current state.
Of course, my Ack might not mean too much because I'm not a maintainer, but I still would expect to be included in 'anyone'.
Arnd
Quoted 32 lines
-----Original Message-----
From: Arnd Bergmann [mailto:[email protected]]
Sent: Wednesday, July 13, 2011 12:03 AM
To: Ashish Jangam
Cc: Mark Brown; [email protected]; [email protected]; Dajun; [email protected]
Subject: Re: [PATCH 01/11] MFD: DA9052 MFD core module v2Quoted 8 lines · On Monday 11 July 2011 08:57:46 Ashish Jangam wrote:
Quoted 8 lines
-----Original Message-----
From: Arnd Bergmann [mailto:[email protected]]
Sent: Tuesday, July 05, 2011 8:25 PM
To: Ashish Jangam
Cc: Mark Brown; [email protected]; [email protected]; Dajun; [email protected]
Subject: Re: [PATCH 01/11] MFD: DA9052 MFD core module v2Quoted 6 lines
Quoted 6 lines · On Tuesday 05 July 2011, ashishj3 wrote:
Quoted 1 line
The DA9052 is a highly integrated PMIC subsystem with supply domain
flexibility
Quoted 3 lines
to support wide range of high performance application.
It provides voltage regulators, GPIO controller, Touch Screen, RTC,
Battery
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines
control and other functionality.
Signed-off-by David Dajun Chen <[email protected]>Signed-off-by Ashish Jangam <[email protected]>Reviewed-by Arnd Bergmann <[email protected]>Can anyone ack this patch?
Quoted 8 lines
What do you think my message was? Reviewed-by is usually stronger than Acked-by, it means that I actually had a closer look and am now happy with the current state.
Of course, my Ack might not mean too much because I'm not a maintainer, but I still would expect to be included in 'anyone'.
Arnd
Sorry for that, since I was not much familiar with this terminology.
Ashish
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�
Quoted 38 lines · On Tue, Jul 05, 2011 at 08:07:00PM +0530, ashishj3 wrote:
The DA9052 is a highly integrated PMIC subsystem with supply domain flexibility to support wide range of high performance application.
It provides voltage regulators, GPIO controller, Touch Screen, RTC, Battery control and other functionality.
Signed-off-by David Dajun Chen <[email protected]>Signed-off-by Ashish Jangam <[email protected]>---
Changes since v2:
- Drop da9052_irqs[] table.
- Move struct da9052_subdev_info[].
- Remove initialization of static member.
- Care for NULL pdatainit().
- Check removal of subdevices on errors.
- Remove open source spi code.
- Remove '_spi' from the driver name.
- Movetbat_lookuptable from header file.
- Removeirq.h
- Removenum_gpiovariable from pdata--- drivers/mfd/Kconfig | 25 ++ drivers/mfd/Makefile | 7 + drivers/mfd/da9052-core.c | 539 +++++++++++++++++++++++++ drivers/mfd/da9052-i2c.c | 168 ++++++++ drivers/mfd/da9052-irq.c | 168 ++++++++ drivers/mfd/da9052-spi.c | 132 +++++++ include/linux/mfd/da9052/da9052.h | 91 +++++ include/linux/mfd/da9052/pdata.h | 43 ++ include/linux/mfd/da9052/reg.h | 777 +++++++++++++++++++++++++++++++++++++ 9 files changed, 1950 insertions(+), 0 deletions(-) create mode 100755 drivers/mfd/da9052-core.c create mode 100755 drivers/mfd/da9052-i2c.c create mode 100755 drivers/mfd/da9052-irq.c create mode 100755 drivers/mfd/da9052-spi.c create mode 100755 include/linux/mfd/da9052/da9052.h create mode 100755 include/linux/mfd/da9052/pdata.h create mode 100755 include/linux/mfd/da9052/reg.h
[...]
drivers/mfd/da9052-core.c line 312
Quoted 12 lines
drivers/mfd/da9052-core.c new file +12
-0+int da9052_reg_update (struct da9052 *da9052,unsigned char reg, +unsigned char bit_mask,unsigned char reg_val) +{ +int ret; +unsigned char val; + +if (reg >DA9052_MAX_REG_CNT ) { +dev_err (da9052->dev,"invalid reg %x\n" , reg); +return -EINVAL ; + } + +mutex_lock_interruptible (&da9052->io_lock);
Compile warning as below.
"warning: ignoring return value of ‘mutex_lock_interruptible’, declared with attribute warn_unused_result"
Quoted 29 lines
drivers/mfd/da9052-core.c new file +29
-0+ +if (da9052->read_dev ==NULL || da9052->write_dev ==NULL ) { + ret = -ENODEV ; + goto err; + } + + ret = da9052->read_dev (da9052, reg,1 , &val); +if (ret <0 ) + goto err; + + val &= ~bit_mask; + val |= reg_val; + + ret = da9052->write_dev (da9052, reg,1 , &val); +if (ret <0 ) + goto err; + +mutex_unlock (&da9052->io_lock); + +return 0 ; + +err: +mutex_unlock (&da9052->io_lock); +return ret; +} +EXPORT_SYMBOL_GPL (da9052_reg_update); + +int da9052_set_bits (struct da9052 *da9052,unsigned char reg, +unsigned char bit_mask)
drivers/mfd/da9052-core.c line 351
Quoted 10 lines
drivers/mfd/da9052-core.c new file +10
-0+{ +unsigned char val; +int ret; + +if (reg >DA9052_MAX_REG_CNT ) { +dev_err (da9052->dev,"invalid reg %x\n" , reg); +return -EINVAL ; + } + +mutex_lock_interruptible (&da9052->io_lock);
ditto
Quoted 28 lines
drivers/mfd/da9052-core.c new file +28
-0+ +if (da9052->read_dev ==NULL || da9052->write_dev ==NULL ) { + ret = -ENODEV ; + goto err; + } + + ret = da9052->read_dev (da9052, reg,1 , &val); +if (ret <0 ) + goto err; + + val |= bit_mask; + + ret = da9052->write_dev (da9052, reg,1 , &val); +if (ret <0 ) + goto err; + +mutex_unlock (&da9052->io_lock); + +return 0 ; + +err: +mutex_unlock (&da9052->io_lock); +return ret; +} +EXPORT_SYMBOL_GPL (da9052_set_bits); + +int da9052_clear_bits (struct da9052 *da9052,unsigned char reg, +unsigned char bit_mask)
drivers/mfd/da9052-core.c line 389
Quoted 10 lines
drivers/mfd/da9052-core.c new file +10
-0+{ +unsigned char val; +int ret; + +if (reg >DA9052_MAX_REG_CNT ) { +dev_err (da9052->dev,"invalid reg %x\n" , reg); +return -EINVAL ; + } + +mutex_lock_interruptible (&da9052->io_lock);
ditto
Quoted 25 lines
drivers/mfd/da9052-core.c new file +25
-0+ +if (da9052->read_dev ==NULL || da9052->write_dev ==NULL ) { + ret = -ENODEV ; + goto err; + } + + ret = da9052->read_dev (da9052, reg,1 , &val); +if (ret <0 ) + goto err; + + val &= ~bit_mask; + + ret = da9052->write_dev (da9052, reg,1 , &val); +if (ret <0 ) + goto err; + +mutex_unlock (&da9052->io_lock); + +return 0 ; + +err: +mutex_unlock (&da9052->io_lock); +return ret; +} +EXPORT_SYMBOL_GPL (da9052_clear_bits);
[...]
Quoted 22 lines
drivers/mfd/da9052-i2c.c new file +22
-0+static int __devinit da9052_i2c_probe (struct i2c_client *client, +const struct i2c_device_id *id) +{ +struct i2c_adapter *adapter; +struct da9052 *da9052_i2c; +int ret; + + da9052_i2c =kzalloc (sizeof (struct da9052 ),GFP_KERNEL ); +if (!da9052_i2c) +return -ENOMEM ; + + adapter =to_i2c_adapter (client->dev.parent); + +if (!i2c_check_functionality (adapter,I2C_FUNC_SMBUS_BYTE_DATA )) { +dev_info (&client->dev,"Error in %s:i2c_check_functionality\n" , + __func__); +return -ENODEV ; + } + + da9052_i2c->i2c_client = client; + da9052_i2c->dev = &client->dev; +
drivers/mfd/da9052-i2c.c line 110
Quoted 10 lines
drivers/mfd/da9052-i2c.c new file +10
-0+i2c_set_clientdata (client, da9052_i2c); + + da9052_i2c->write_dev = da9052_i2c_write_device; + da9052_i2c->read_dev = da9052_i2c_read_device; + + ret =da9052_i2c_enable_multiwrite (da9052_i2c); +if (ret <0 ) + goto err; + + ret =da9052_device_init (da9052_i2c)
The semicolon was missed there.
Quoted 9 lines
drivers/mfd/da9052-i2c.c new file +9
-0+if (ret !=0 ) + goto err; + +return 0 ; + +err: +kfree (da9052_i2c); +return ret; +}
[...]
Quoted 4 lines
drivers/mfd/da9052-spi.c new file +4
-0+int da9052_spi_read_device (struct da9052 *da9052,unsigned char reg, +unsigned bytes,unsigned char *val) +{ +int ret, raddr;
drivers/mfd/da9052-spi.c line 54
Quoted 10 lines
drivers/mfd/da9052-spi.c new file +10
-0+ +for (raddr = reg; raddr < reg + bytes; raddr++) { + reg = ((raddr <<1 ) | da9052->rw_pol); + ret =spi_write_then_read (da9052->spi_dev, (u8 *)®,2 , + val,2 ); +if (ret !=0 ) +return ret; + } + +return ret;
warning: ‘ret’ may be used uninitialized in this function
Quoted 14 lines
drivers/mfd/da9052-spi.c new file +14
-0+} + +static int da9052_spi_probe (struct spi_device *spi) +{ +int ret; +struct da9052 *da9052_spi =kzalloc (sizeof (struct da9052 ),GFP_KERNEL ); + +if (!da9052_spi) +return -ENOMEM ; + + spi->mode =SPI_MODE_0 |SPI_CPOL ; + spi->bits_per_word =8 ; +spi_setup (spi); +
drivers/mfd/da9052-spi.c line 78
Quoted 10 lines
drivers/mfd/da9052-spi.c new file +10
-0+ da9052_spi->dev = &spi->dev; + da9052_spi->spi_dev = spi; + + da9052_spi->rw_pol =1 ; +dev_set_drvdata (&spi->dev, da9052_spi); + + da9052_spi->write_dev = da9052_spi_write_device; + da9052_spi->read_dev = da9052_spi_read_device; + + ret =da9052_device_init (da9052_i2c)
s/da9052_i2c/da9052_spi? Also, semicolon was missed there.
Signature · 2 lines
Regards, Shawn
Quoted 8 lines · Shawn Guo
Review
Quoted 1 line · On Tue, Jul 05, 2011 at 08:07:00PM +0530, ashishj3 wrote:
(quoted diff) +1
-0+ mutex_lock_interruptible(&da9052->io_lock);Compile warning as below.
"warning: ignoring return value of ‘mutex_lock_interruptible’, declared with attribute
warn_unused_result"
Although the bigger problem is why are these interruptible? That's very unusual.
Quoted 5 lines · On Thursday 21 July 2011 16:47:48 Mark Brown wrote:
Quoted 3 lines · Shawn Guo
Quoted 1 line · On Tue, Jul 05, 2011 at 08:07:00PM +0530, ashishj3 wrote:
+
mutex_lock_interruptible(&da9052->io_lock);
Quoted 7 lines
Quoted 4 lines
Compile warning as below.
"warning: ignoring return value of ‘mutex_lock_interruptible’, declared with attribute
warn_unused_result"Although the bigger problem is why are these interruptible? That's very unusual.
Well, the default should really be to use _interruptible or at least _killable with the appropriate error handling, and only use noninterruptible locks in cases where that's not possible.
In the funtions that Shawn pointed out, there is an error return, so it would be possible to do that, but the callers would need to be audited carefully.
Arnd
Quoted 11 lines · Arnd Bergmann
Quoted 2 lines · On Thursday 21 July 2011 16:47:48 Mark Brown wrote:
Although the bigger problem is why are these interruptible? That's very unusual.
Well, the default should really be to use
_interruptibleor at least_killablewith the appropriate error handling, and only use noninterruptible locks in cases where that's not possible.In the funtions that Shawn pointed out, there is an error return, so it would be possible to do that, but the callers would need to be audited carefully.
We went round this analysis already with the underlying I2C drivers (which also end up needing to take mutexes and so on) - it really does work out better to just make the I/O noninterruptible, the I/O is fast enough to not really be worth interrupting and the handling for actual I/O errors should normally be sufficiently different to that for user initiated aborts that it just adds complication.
For example, if the user interrupts while we're in the middle of some lengthy series of operations or wait what we really want to do is to tear down the high level thing we're doing in an orderly fashion. If we allow the interrupt to be noticed as part of an I/O operation then what we often end up doing is failing that and we then have to work out why the I/O failed, if actually happened on a physical level and how we deal with that. Usually none of these paths will be well tested.
The overall result is that the system generally becomes more complicated and less robust.
Quoted 15 lines · Mark Brown
We went round this analysis already with the underlying I2C drivers (which also end up needing to take mutexes and so on) - it really does work out better to just make the I/O noninterruptible, the I/O is fast enough to not really be worth interrupting and the handling for actual I/O errors should normally be sufficiently different to that for user initiated aborts that it just adds complication.
For example, if the user interrupts while we're in the middle of some lengthy series of operations or wait what we really want to do is to tear down the high level thing we're doing in an orderly fashion. If we allow the interrupt to be noticed as part of an I/O operation then what we often end up doing is failing that and we then have to work out why the I/O failed, if actually happened on a physical level and how we deal with that. Usually none of these paths will be well tested.
Quoted 2 lines
The overall result is that the system generally becomes more complicated and less robust.
Yes, that makes sense. There are also cases where a mutex should really be a spinlock (which is by definition not interruptible), or vice versa. I don't know if this is one of them.
I agree that the safest solution here is to just make the mutex uninterruptible.
Arnd
Quoted 3 lines · Arnd Bergmann
Yes, that makes sense. There are also cases where a mutex should really be a spinlock (which is by definition not interruptible), or vice versa. I don't know if this is one of them.
We would be using spinlocks except the underlying buses sleep waiting for the hardware to complete the transfer - the operations are quick enough from a user perspective but at the very low level we want the CPU to be able to go off and do other things while they're happening.
Quoted 9 lines · On Tue, Jul 05, 2011 at 08:07:00PM +0530, ashishj3 wrote:
The DA9052 is a highly integrated PMIC subsystem with supply domain flexibility to support wide range of high performance application.
It provides voltage regulators, GPIO controller, Touch Screen, RTC, Battery control and other functionality.
Signed-off-by David Dajun Chen <[email protected]>Signed-off-by Ashish Jangam <[email protected]>---
[...]
Quoted 31 lines
include/linux/mfd/da9052/pdata.h new file +25
-0@@ -0,0 +1,43 @@ +/* +* Platform data declarations for DA9052 PMICs. +* +* Copyright(c) 2011 Dialog Semiconductor Ltd. +* +* Author: David Dajun Chen <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +*/ + +#ifndef __MFD_DA9052_PDATA_H__ +#define __MFD_DA9052_PDATA_H__
include/linux/mfd/da9052/pdata.h line 35
Quoted 10 lines
include/linux/mfd/da9052/pdata.h new file +10
-0+ +#define DA9052_MAX_REGULATORS 15 + +struct da9052 ; + +struct da9052_pdata { +struct led_platform_data *pled; +struct da9052_wdt_platform_data *pwdt; +struct da9052_tsi_platform_data *ptsi; +int (*init) (struct da9052 *da9052);
Do you have any actually example to demonstrate the necessity of this hook? Otherwise, I would suggest we drop it, since machine code can always do whatever setup needed there.
I'm asking because this kind of hooks always get in the way of the device tree conversion.
Regards,
Shawn
Quoted 6 lines
include/linux/mfd/da9052/pdata.h new file +6
-0+int irq; +int irq_base; +int num_regulators; +int gpio_base; +struct regulator_init_data *regulators[DA9052_MAX_REGULATORS ]; +};
drivers/mfd/da9052-core.c line 351
Quoted 12 lines · On Tue, Jul 05, 2011 at 08:07:00PM +0530, ashishj3 wrote:
drivers/mfd/da9052-core.c new file +12
-0+int da9052_set_bits (struct da9052 *da9052,unsigned char reg, +unsigned char bit_mask) +{ +unsigned char val; +int ret; + +if (reg >DA9052_MAX_REG_CNT ) { +dev_err (da9052->dev,"invalid reg %x\n" , reg); +return -EINVAL ; + } + +mutex_lock_interruptible (&da9052->io_lock);
Linus has now merged the regmap code (include/linux/regmap.h and drivers/base/regmap) which means that your register I/O code should probably be redone in terms of that - it shoud factor a lot of code out of the driver.