diff options
| author | Greg Kroah-Hartman <greg@kroah.com> | 2004-05-14 01:21:10 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <greg@kroah.com> | 2004-05-14 01:21:10 -0700 |
| commit | 744804bcdeaef29a736421bd0f2b0eddcfa9f879 (patch) | |
| tree | e4bf9bc7b7ec548852fc2e57975fb00e1ebd9ae6 | |
| parent | 141baf80514374935d084c12f2f1e426e9cea5a0 (diff) | |
| parent | 558fcd724e9016b1af08d796f7e762b7dcc6117a (diff) | |
Merge kroah.com:/home/greg/linux/BK/bleed-2.6
into kroah.com:/home/greg/linux/BK/i2c-2.6
71 files changed, 1059 insertions, 387 deletions
diff --git a/Documentation/i2c/porting-clients b/Documentation/i2c/porting-clients index 886d605ce33d..18b9acef0def 100644 --- a/Documentation/i2c/porting-clients +++ b/Documentation/i2c/porting-clients @@ -62,9 +62,9 @@ Technical changes: patch to the Documentation/i2c/sysfs-interface file. * [Attach] For I2C drivers, the attach function should make sure - that the adapter's class has I2C_ADAP_CLASS_SMBUS, using the + that the adapter's class has I2C_CLASS_HWMON, using the following construct: - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; ISA-only drivers of course don't need this. diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index f72313b10dc1..71b353bb7396 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -476,8 +476,9 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route case PCI_DEVICE_ID_INTEL_82801DB_0: case PCI_DEVICE_ID_INTEL_82801E_0: case PCI_DEVICE_ID_INTEL_82801EB_0: - case PCI_DEVICE_ID_INTEL_ESB_0: + case PCI_DEVICE_ID_INTEL_ESB_1: case PCI_DEVICE_ID_INTEL_ICH6_0: + case PCI_DEVICE_ID_INTEL_ICH6_1: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index efcb775246f1..afbd48fe8806 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -381,7 +381,13 @@ static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) break; } - if ( count > 1 ) { /* send ack */ + temp++; + count--; + + if (msg->flags & I2C_M_NO_RD_ACK) + continue; + + if ( count > 0 ) { /* send ack */ sdalo(adap); DEBPROTO(printk(" Am ")); } else { @@ -395,8 +401,6 @@ static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) }; scllo(adap); sdahi(adap); - temp++; - count--; } return rdcount; } diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 65a118038c92..c6a9ba477eb5 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -95,6 +95,8 @@ config I2C_I801 82801CA/CAM 82801DB 82801EB + 6300ESB + ICH6 This driver can also be built as a module. If so, the module will be called i2c-i801. @@ -145,16 +147,16 @@ config I2C_ITE This support is also available as a module. If so, the module will be called i2c-ite. -config I2C_IXP42X - tristate "IXP42x GPIO-Based I2C Interface" - depends on I2C && ARCH_IXP425 +config I2C_IXP4XX + tristate "IXP4xx GPIO-Based I2C Interface" + depends on I2C && ARCH_IXP4XX select I2C_ALGOBIT help - Say Y here if you have an Intel IXP42x(420,421,422,425) based + Say Y here if you have an Intel IXP4xx(420,421,422,425) based system and are using GPIO lines for an I2C bus. This support is also available as a module. If so, the module - will be called i2c-ixp42x. + will be called i2c-ixp4xx. config I2C_KEYWEST tristate "Powermac Keywest I2C interface" diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 13d07d54a48b..83391986c5e6 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o obj-$(CONFIG_I2C_ISA) += i2c-isa.o obj-$(CONFIG_I2C_ITE) += i2c-ite.o -obj-$(CONFIG_I2C_IXP42X) += i2c-ixp42x.o +obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 6715b0d14c04..e7fce45bb061 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -480,7 +480,7 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter ali1535_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, .name = "unset", }; diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 3807c96821f1..9b55cbbf293e 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -357,7 +357,7 @@ static struct i2c_algorithm ali1563_algorithm = { static struct i2c_adapter ali1563_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .algo = &ali1563_algorithm, }; diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index 446606c91776..673baa5be9d6 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -470,7 +470,7 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter ali15x3_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, .name = "unset", }; diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 261b5d916986..2a273e472948 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -303,7 +303,7 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter amd756_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, .name = "unset", }; diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 7ad6f7e501a3..54704be10404 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -359,7 +359,7 @@ static int __devinit amd8111_probe(struct pci_dev *dev, const struct pci_device_ smbus->adapter.owner = THIS_MODULE; snprintf(smbus->adapter.name, I2C_NAME_SIZE, "SMBus2 AMD8111 adapter at %04x", smbus->base); - smbus->adapter.class = I2C_ADAP_CLASS_SMBUS; + smbus->adapter.class = I2C_CLASS_HWMON; smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo_data = smbus; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index d0612fb8ddb1..22c71d7939ab 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -28,7 +28,8 @@ 82801CA/CAM 2483 82801DB 24C3 (HW PEC supported, 32 byte buffer not supported) 82801EB 24D3 (HW PEC supported, 32 byte buffer not supported) - + 6300ESB 25A4 + ICH6 266A This driver supports several versions of Intel's I/O Controller Hubs (ICH). For SMBus support, they are similar to the PIIX4 and are part of Intel's '810' and other chipsets. @@ -121,7 +122,8 @@ static int i801_setup(struct pci_dev *dev) I801_dev = dev; if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) || - (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3)) + (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3) || + (dev->device == PCI_DEVICE_ID_INTEL_ESB_4)) isich4 = 1; else isich4 = 0; @@ -539,7 +541,7 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter i801_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, .name = "unset", }; @@ -576,10 +578,22 @@ static struct pci_device_id i801_ids[] = { .subdevice = PCI_ANY_ID, }, { - .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_DEVICE_ID_INTEL_82801EB_3, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_82801EB_3, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_ESB_4, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_ICH6_16, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, }, { 0, } }; diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index 73387ad26934..0f54a2a0afa5 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c @@ -43,7 +43,7 @@ static struct i2c_algorithm isa_algorithm = { /* There can only be one... */ static struct i2c_adapter isa_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .algo = &isa_algorithm, .name = "ISA main adapter", }; diff --git a/drivers/i2c/busses/i2c-ixp42x.c b/drivers/i2c/busses/i2c-ixp42x.c deleted file mode 100644 index 59fcb70fd252..000000000000 --- a/drivers/i2c/busses/i2c-ixp42x.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * drivers/i2c/i2c-adap-ixp42x.c - * - * Intel's IXP42x XScale NPU chipsets (IXP420, 421, 422, 425) do not have - * an on board I2C controller but provide 16 GPIO pins that are often - * used to create an I2C bus. This driver provides an i2c_adapter - * interface that plugs in under algo_bit and drives the GPIO pins - * as instructed by the alogorithm driver. - * - * Author: Deepak Saxena <dsaxena@plexity.net> - * - * Copyright (c) 2003-2004 MontaVista Software Inc. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - * - * NOTE: Since different platforms will use different GPIO pins for - * I2C, this driver uses an IXP42x-specific platform_data - * pointer to pass the GPIO numbers to the driver. This - * allows us to support all the different IXP42x platforms - * w/o having to put #ifdefs in this driver. - * - * See arch/arm/mach-ixp42x/ixdp425.c for an example of building a - * device list and filling in the ixp42x_i2c_pins data structure - * that is passed as the platform_data to this driver. - */ - -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/module.h> -#include <linux/i2c.h> - -#include <asm/hardware.h> /* Pick up IXP42x-specific bits */ - -static inline int ixp42x_scl_pin(void *data) -{ - return ((struct ixp42x_i2c_pins*)data)->scl_pin; -} - -static inline int ixp42x_sda_pin(void *data) -{ - return ((struct ixp42x_i2c_pins*)data)->sda_pin; -} - -static void ixp42x_bit_setscl(void *data, int val) -{ - gpio_line_set(ixp42x_scl_pin(data), 0); - gpio_line_config(ixp42x_scl_pin(data), - val ? IXP425_GPIO_IN : IXP425_GPIO_OUT ); -} - -static void ixp42x_bit_setsda(void *data, int val) -{ - gpio_line_set(ixp42x_sda_pin(data), 0); - gpio_line_config(ixp42x_sda_pin(data), - val ? IXP425_GPIO_IN : IXP425_GPIO_OUT ); -} - -static int ixp42x_bit_getscl(void *data) -{ - int scl; - - gpio_line_config(ixp42x_scl_pin(data), IXP425_GPIO_IN ); - gpio_line_get(ixp42x_scl_pin(data), &scl); - - return scl; -} - -static int ixp42x_bit_getsda(void *data) -{ - int sda; - - gpio_line_config(ixp42x_sda_pin(data), IXP425_GPIO_IN ); - gpio_line_get(ixp42x_sda_pin(data), &sda); - - return sda; -} - -struct ixp42x_i2c_data { - struct ixp42x_i2c_pins *gpio_pins; - struct i2c_adapter adapter; - struct i2c_algo_bit_data algo_data; -}; - -static int ixp42x_i2c_remove(struct device *dev) -{ - struct platform_device *plat_dev = to_platform_device(dev); - struct ixp42x_i2c_data *drv_data = dev_get_drvdata(&plat_dev->dev); - - dev_set_drvdata(&plat_dev->dev, NULL); - - i2c_bit_del_bus(&drv_data->adapter); - - kfree(drv_data); - - return 0; -} - -static int ixp42x_i2c_probe(struct device *dev) -{ - int err; - struct platform_device *plat_dev = to_platform_device(dev); - struct ixp42x_i2c_pins *gpio = plat_dev->dev.platform_data; - struct ixp42x_i2c_data *drv_data = - kmalloc(sizeof(struct ixp42x_i2c_data), GFP_KERNEL); - - if(!drv_data) - return -ENOMEM; - - memzero(drv_data, sizeof(struct ixp42x_i2c_data)); - drv_data->gpio_pins = gpio; - - /* - * We could make a lot of these structures static, but - * certain platforms may have multiple GPIO-based I2C - * buses for various device domains, so we need per-device - * algo_data->data. - */ - drv_data->algo_data.data = gpio; - drv_data->algo_data.setsda = ixp42x_bit_setsda; - drv_data->algo_data.setscl = ixp42x_bit_setscl; - drv_data->algo_data.getsda = ixp42x_bit_getsda; - drv_data->algo_data.getscl = ixp42x_bit_getscl; - drv_data->algo_data.udelay = 10; - drv_data->algo_data.mdelay = 10; - drv_data->algo_data.timeout = 100; - - drv_data->adapter.id = I2C_HW_B_IXP425, - drv_data->adapter.algo_data = &drv_data->algo_data, - - drv_data->adapter.dev.parent = &plat_dev->dev; - - gpio_line_config(gpio->scl_pin, IXP425_GPIO_IN); - gpio_line_config(gpio->sda_pin, IXP425_GPIO_IN); - gpio_line_set(gpio->scl_pin, 0); - gpio_line_set(gpio->sda_pin, 0); - - if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) { - printk(KERN_ERR "ERROR: Could not install %s\n", dev->bus_id); - - kfree(drv_data); - return err; - } - - dev_set_drvdata(&plat_dev->dev, drv_data); - - return 0; -} - -static struct device_driver ixp42x_i2c_driver = { - .name = "IXP42X-I2C", - .bus = &platform_bus_type, - .probe = ixp42x_i2c_probe, - .remove = ixp42x_i2c_remove, -}; - -static int __init ixp42x_i2c_init(void) -{ - return driver_register(&ixp42x_i2c_driver); -} - -static void __exit ixp42x_i2c_exit(void) -{ - driver_unregister(&ixp42x_i2c_driver); -} - -module_init(ixp42x_i2c_init); -module_exit(ixp42x_i2c_exit); - -MODULE_DESCRIPTION("GPIO-based I2C driver for IXP42x systems"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); - diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c new file mode 100644 index 000000000000..d8bfd59c1dc0 --- /dev/null +++ b/drivers/i2c/busses/i2c-ixp4xx.c @@ -0,0 +1,181 @@ +/* + * drivers/i2c/i2c-adap-ixp4xx.c + * + * Intel's IXP4xx XScale NPU chipsets (IXP420, 421, 422, 425) do not have + * an on board I2C controller but provide 16 GPIO pins that are often + * used to create an I2C bus. This driver provides an i2c_adapter + * interface that plugs in under algo_bit and drives the GPIO pins + * as instructed by the alogorithm driver. + * + * Author: Deepak Saxena <dsaxena@plexity.net> + * + * Copyright (c) 2003-2004 MontaVista Software Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * NOTE: Since different platforms will use different GPIO pins for + * I2C, this driver uses an IXP4xx-specific platform_data + * pointer to pass the GPIO numbers to the driver. This + * allows us to support all the different IXP4xx platforms + * w/o having to put #ifdefs in this driver. + * + * See arch/arm/mach-ixp4xx/ixdp425.c for an example of building a + * device list and filling in the ixp4xx_i2c_pins data structure + * that is passed as the platform_data to this driver. + */ + +#include <linux/config.h> +#ifdef CONFIG_I2C_DEBUG_BUS +#define DEBUG 1 +#endif + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/module.h> +#include <linux/i2c.h> +#include <linux/i2c-algo-bit.h> + +#include <asm/hardware.h> /* Pick up IXP4xx-specific bits */ + +static inline int ixp4xx_scl_pin(void *data) +{ + return ((struct ixp4xx_i2c_pins*)data)->scl_pin; +} + +static inline int ixp4xx_sda_pin(void *data) +{ + return ((struct ixp4xx_i2c_pins*)data)->sda_pin; +} + +static void ixp4xx_bit_setscl(void *data, int val) +{ + gpio_line_set(ixp4xx_scl_pin(data), 0); + gpio_line_config(ixp4xx_scl_pin(data), + val ? IXP4XX_GPIO_IN : IXP4XX_GPIO_OUT ); +} + +static void ixp4xx_bit_setsda(void *data, int val) +{ + gpio_line_set(ixp4xx_sda_pin(data), 0); + gpio_line_config(ixp4xx_sda_pin(data), + val ? IXP4XX_GPIO_IN : IXP4XX_GPIO_OUT ); +} + +static int ixp4xx_bit_getscl(void *data) +{ + int scl; + + gpio_line_config(ixp4xx_scl_pin(data), IXP4XX_GPIO_IN ); + gpio_line_get(ixp4xx_scl_pin(data), &scl); + + return scl; +} + +static int ixp4xx_bit_getsda(void *data) +{ + int sda; + + gpio_line_config(ixp4xx_sda_pin(data), IXP4XX_GPIO_IN ); + gpio_line_get(ixp4xx_sda_pin(data), &sda); + + return sda; +} + +struct ixp4xx_i2c_data { + struct ixp4xx_i2c_pins *gpio_pins; + struct i2c_adapter adapter; + struct i2c_algo_bit_data algo_data; +}; + +static int ixp4xx_i2c_remove(struct device *dev) +{ + struct platform_device *plat_dev = to_platform_device(dev); + struct ixp4xx_i2c_data *drv_data = dev_get_drvdata(&plat_dev->dev); + + dev_set_drvdata(&plat_dev->dev, NULL); + + i2c_bit_del_bus(&drv_data->adapter); + + kfree(drv_data); + + return 0; +} + +static int ixp4xx_i2c_probe(struct device *dev) +{ + int err; + struct platform_device *plat_dev = to_platform_device(dev); + struct ixp4xx_i2c_pins *gpio = plat_dev->dev.platform_data; + struct ixp4xx_i2c_data *drv_data = + kmalloc(sizeof(struct ixp4xx_i2c_data), GFP_KERNEL); + + if(!drv_data) + return -ENOMEM; + + memzero(drv_data, sizeof(struct ixp4xx_i2c_data)); + drv_data->gpio_pins = gpio; + + /* + * We could make a lot of these structures static, but + * certain platforms may have multiple GPIO-based I2C + * buses for various device domains, so we need per-device + * algo_data->data. + */ + drv_data->algo_data.data = gpio; + drv_data->algo_data.setsda = ixp4xx_bit_setsda; + drv_data->algo_data.setscl = ixp4xx_bit_setscl; + drv_data->algo_data.getsda = ixp4xx_bit_getsda; + drv_data->algo_data.getscl = ixp4xx_bit_getscl; + drv_data->algo_data.udelay = 10; + drv_data->algo_data.mdelay = 10; + drv_data->algo_data.timeout = 100; + + drv_data->adapter.id = I2C_HW_B_IXP4XX, + drv_data->adapter.algo_data = &drv_data->algo_data, + + drv_data->adapter.dev.parent = &plat_dev->dev; + + gpio_line_config(gpio->scl_pin, IXP4XX_GPIO_IN); + gpio_line_config(gpio->sda_pin, IXP4XX_GPIO_IN); + gpio_line_set(gpio->scl_pin, 0); + gpio_line_set(gpio->sda_pin, 0); + + if ((err = i2c_bit_add_bus(&drv_data->adapter) != 0)) { + printk(KERN_ERR "ERROR: Could not install %s\n", dev->bus_id); + + kfree(drv_data); + return err; + } + + dev_set_drvdata(&plat_dev->dev, drv_data); + + return 0; +} + +static struct device_driver ixp4xx_i2c_driver = { + .name = "IXP4XX-I2C", + .bus = &platform_bus_type, + .probe = ixp4xx_i2c_probe, + .remove = ixp4xx_i2c_remove, +}; + +static int __init ixp4xx_i2c_init(void) +{ + return driver_register(&ixp4xx_i2c_driver); +} + +static void __exit ixp4xx_i2c_exit(void) +{ + driver_unregister(&ixp4xx_i2c_driver); +} + +module_init(ixp4xx_i2c_init); +module_exit(ixp4xx_i2c_exit); + +MODULE_DESCRIPTION("GPIO-based I2C adapter for IXP4xx systems"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); + diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index 3c65c9d030e8..0b606e88d47a 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c @@ -48,7 +48,6 @@ #include <linux/config.h> #include <linux/module.h> -#include <linux/config.h> #include <linux/kernel.h> #include <linux/ioport.h> #include <linux/pci.h> diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 214f5644cc55..774a7ef52d43 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -119,7 +119,7 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter nforce2_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, .name = "unset", }; diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c index c73fadc061a7..6798954f0056 100644 --- a/drivers/i2c/busses/i2c-parport-light.c +++ b/drivers/i2c/busses/i2c-parport-light.c @@ -112,7 +112,7 @@ static struct i2c_algo_bit_data parport_algo_data = { static struct i2c_adapter parport_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .id = I2C_HW_B_LP, .algo_data = &parport_algo_data, .name = "Parallel port adapter (light)", diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 6a9b764caada..e9560bab51c4 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c @@ -147,7 +147,7 @@ static struct i2c_algo_bit_data parport_algo_data = { static struct i2c_adapter parport_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .id = I2C_HW_B_LP, .name = "Parallel port adapter", }; diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 8edc957e51c5..0beca9e9b23d 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -31,7 +31,6 @@ #include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> -#include <linux/config.h> #include <linux/pci.h> #include <linux/kernel.h> #include <linux/stddef.h> @@ -410,7 +409,7 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter piix4_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, .name = "unset", }; diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index 90b72690994a..ec615af7be04 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -360,7 +360,7 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter sis5595_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .name = "unset", .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 516f51abe901..b7823c260364 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -456,7 +456,7 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter sis630_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .name = "unset", .algo = &smbus_algorithm, }; diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index c1d456b049a0..7c053abcea7a 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -260,7 +260,7 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter sis96x_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, .name = "unset", }; diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c index 6ed3ff080630..fba8f0eae3a4 100644 --- a/drivers/i2c/busses/i2c-via.c +++ b/drivers/i2c/busses/i2c-via.c @@ -88,7 +88,7 @@ static struct i2c_algo_bit_data bit_data = { static struct i2c_adapter vt586b_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .name = "VIA i2c", .algo_data = &bit_data, }; diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index c45b33f3802f..fc207253d203 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -289,7 +289,7 @@ static struct i2c_algorithm smbus_algorithm = { static struct i2c_adapter vt596_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_SMBUS, + .class = I2C_CLASS_HWMON, .algo = &smbus_algorithm, .name = "unset", }; diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c index 3d4fad692993..efb677d24976 100644 --- a/drivers/i2c/busses/i2c-voodoo3.c +++ b/drivers/i2c/busses/i2c-voodoo3.c @@ -167,7 +167,7 @@ static struct i2c_algo_bit_data voo_i2c_bit_data = { static struct i2c_adapter voodoo3_i2c_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_TV_ANALOG, + .class = I2C_CLASS_TV_ANALOG, .name = "I2C Voodoo3/Banshee adapter", .algo_data = &voo_i2c_bit_data, }; @@ -184,7 +184,7 @@ static struct i2c_algo_bit_data voo_ddc_bit_data = { static struct i2c_adapter voodoo3_ddc_adapter = { .owner = THIS_MODULE, - .class = I2C_ADAP_CLASS_DDC, + .class = I2C_CLASS_DDC, .name = "DDC Voodoo3/Banshee adapter", .algo_data = &voo_ddc_bit_data, }; diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 2a33ae416782..61ddd65e53ca 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -25,7 +25,6 @@ */ #include <linux/config.h> -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/kernel.h> diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c index 14bcb0aee2eb..b472fe81a82b 100644 --- a/drivers/i2c/busses/scx200_i2c.c +++ b/drivers/i2c/busses/scx200_i2c.c @@ -22,7 +22,6 @@ */ #include <linux/config.h> -#include <linux/config.h> #include <linux/module.h> #include <linux/errno.h> #include <linux/kernel.h> diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig index e005b02484b8..d6902c60aa1b 100644 --- a/drivers/i2c/chips/Kconfig +++ b/drivers/i2c/chips/Kconfig @@ -136,11 +136,11 @@ config SENSORS_LM85 config SENSORS_LM90 tristate "National Semiconductor LM90 and compatibles" - depends on I2C && EXPERIMENTAL + depends on I2C select I2C_SENSOR help - If you say yes here you get support for National Semiconductor LM90 - and Analog Devices ADM1032 sensor chips. + If you say yes here you get support for National Semiconductor LM90, + LM89 and LM99, and Analog Devices ADM1032 sensor chips. This driver can also be built as a module. If so, the module will be called lm90. @@ -163,7 +163,7 @@ config SENSORS_W83781D select I2C_SENSOR help If you say yes here you get support for the Winbond W8378x series - of sensor chips: the W83781D, W83782D, W83783S and W83682HF, + of sensor chips: the W83781D, W83782D, W83783S and W83627HF, and the similar Asus AS99127F. This driver can also be built as a module. If so, the module @@ -230,4 +230,14 @@ config SENSORS_PCF8591 This driver can also be built as a module. If so, the module will be called pcf8591. +config SENSORS_RTC8564 + tristate "Epson 8564 RTC chip" + depends on I2C && EXPERIMENTAL + select I2C_SENSOR + help + If you say yes here you get support for the Epson 8564 RTC chip. + + This driver can also be built as a module. If so, the module + will be called i2c-rtc8564. + endmenu diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile index 6de7d4711612..2268f5bbba69 100644 --- a/drivers/i2c/chips/Makefile +++ b/drivers/i2c/chips/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_SENSORS_LM85) += lm85.o obj-$(CONFIG_SENSORS_LM90) += lm90.o obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o +obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o diff --git a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c index 5010461ccf29..73ca01db6e75 100644 --- a/drivers/i2c/chips/adm1021.c +++ b/drivers/i2c/chips/adm1021.c @@ -200,7 +200,7 @@ static DEVICE_ATTR(die_code, S_IRUGO, show_die_code, NULL); static int adm1021_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, adm1021_detect); } diff --git a/drivers/i2c/chips/asb100.c b/drivers/i2c/chips/asb100.c index 355972cff6d9..f93b6f67696e 100644 --- a/drivers/i2c/chips/asb100.c +++ b/drivers/i2c/chips/asb100.c @@ -609,7 +609,7 @@ static DEVICE_ATTR(fan1_pwm_enable, S_IRUGO | S_IWUSR, */ static int asb100_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, asb100_detect); } @@ -855,7 +855,13 @@ static int asb100_detach_client(struct i2c_client *client) return err; } - kfree(i2c_get_clientdata(client)); + if (i2c_get_clientdata(client)==NULL) { + /* subclients */ + kfree(client); + } else { + /* main client */ + kfree(i2c_get_clientdata(client)); + } return 0; } diff --git a/drivers/i2c/chips/fscher.c b/drivers/i2c/chips/fscher.c index 1901a524a845..ab5b70f8624d 100644 --- a/drivers/i2c/chips/fscher.c +++ b/drivers/i2c/chips/fscher.c @@ -293,7 +293,7 @@ do { \ static int fscher_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, fscher_detect); } diff --git a/drivers/i2c/chips/gl518sm.c b/drivers/i2c/chips/gl518sm.c index 3258a2892836..3481ddbf0044 100644 --- a/drivers/i2c/chips/gl518sm.c +++ b/drivers/i2c/chips/gl518sm.c @@ -335,7 +335,7 @@ static DEVICE_ATTR(beep_mask, S_IWUSR|S_IRUGO, static int gl518_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, gl518_detect); } diff --git a/drivers/i2c/chips/it87.c b/drivers/i2c/chips/it87.c index 856d5f57291b..061a0b8009b5 100644 --- a/drivers/i2c/chips/it87.c +++ b/drivers/i2c/chips/it87.c @@ -49,6 +49,54 @@ static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END }; /* Insmod parameters */ SENSORS_INSMOD_1(it87); +#define REG 0x2e /* The register to read/write */ +#define DEV 0x07 /* Register: Logical device select */ +#define VAL 0x2f /* The value to read/write */ +#define PME 0x04 /* The device with the fan registers in it */ +#define DEVID 0x20 /* Register: Device ID */ + +static inline void +superio_outb(int reg, int val) +{ + outb(reg, REG); + outb(val, VAL); +} + +static inline int +superio_inb(int reg) +{ + outb(reg, REG); + return inb(VAL); +} + +static inline void +superio_select(void) +{ + outb(DEV, REG); + outb(PME, VAL); +} + +static inline void +superio_enter(void) +{ + outb(0x87, REG); + outb(0x01, REG); + outb(0x55, REG); + outb(0x55, REG); +} + +static inline void +superio_exit(void) +{ + outb(0x02, REG); + outb(0x02, VAL); +} + +/* just IT8712F for now - this should be extended to support the other + chips as well */ +#define IT8712F_DEVID 0x8712 +#define IT87_ACT_REG 0x30 +#define IT87_BASE_REG 0x60 /* Update battery voltage after every reading if true */ static int update_vbat; @@ -158,6 +206,7 @@ struct it87_data { static int it87_attach_adapter(struct i2c_adapter *adapter); +static int it87_find(int *address); static int it87_detect(struct i2c_adapter *adapter, int address, int kind); static int it87_detach_client(struct i2c_client *client); @@ -500,11 +549,35 @@ static DEVICE_ATTR(alarms, S_IRUGO | S_IWUSR, show_alarms, NULL); * when a new adapter is inserted (and it87_driver is still present) */ static int it87_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, it87_detect); } +/* SuperIO detection - will change normal_isa[0] if a chip is found */ +static int it87_find(int *address) +{ + u16 val; + + superio_enter(); + val = (superio_inb(DEVID) << 8) | + superio_inb(DEVID + 1); + if (val != IT8712F_DEVID) { + superio_exit(); + return -ENODEV; + } + + superio_select(); + val = (superio_inb(IT87_BASE_REG) << 8) | + superio_inb(IT87_BASE_REG + 1); + superio_exit(); + *address = val & ~(IT87_EXTENT - 1); + if (*address == 0) { + return -ENODEV; + } + return 0; +} + /* This function is called by i2c_detect */ int it87_detect(struct i2c_adapter *adapter, int address, int kind) { @@ -853,6 +926,11 @@ static struct it87_data *it87_update_device(struct device *dev) static int __init sm_it87_init(void) { + int addr; + + if (!it87_find(&addr)) { + normal_isa[0] = addr; + } return i2c_add_driver(&it87_driver); } diff --git a/drivers/i2c/chips/lm75.c b/drivers/i2c/chips/lm75.c index 5c6ebdc096ea..e431db905e39 100644 --- a/drivers/i2c/chips/lm75.c +++ b/drivers/i2c/chips/lm75.c @@ -105,7 +105,7 @@ static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL); static int lm75_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, lm75_detect); } diff --git a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c index 2d697f4282f6..74a1ca76cc04 100644 --- a/drivers/i2c/chips/lm78.c +++ b/drivers/i2c/chips/lm78.c @@ -488,7 +488,7 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); * when a new adapter is inserted (and lm78_driver is still present) */ static int lm78_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, lm78_detect); } diff --git a/drivers/i2c/chips/lm80.c b/drivers/i2c/chips/lm80.c index ec8cbe68d755..fe78d98a61bf 100644 --- a/drivers/i2c/chips/lm80.c +++ b/drivers/i2c/chips/lm80.c @@ -376,7 +376,7 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); static int lm80_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, lm80_detect); } diff --git a/drivers/i2c/chips/lm83.c b/drivers/i2c/chips/lm83.c index f50e9344662d..f6023e989dd5 100644 --- a/drivers/i2c/chips/lm83.c +++ b/drivers/i2c/chips/lm83.c @@ -216,7 +216,7 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); static int lm83_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, lm83_detect); } diff --git a/drivers/i2c/chips/lm90.c b/drivers/i2c/chips/lm90.c index 111781a5069d..f28b6679fe6d 100644 --- a/drivers/i2c/chips/lm90.c +++ b/drivers/i2c/chips/lm90.c @@ -1,7 +1,7 @@ /* * lm90.c - Part of lm_sensors, Linux kernel modules for hardware * monitoring - * Copyright (C) 2003 Jean Delvare <khali@linux-fr.org> + * Copyright (C) 2003-2004 Jean Delvare <khali@linux-fr.org> * * Based on the lm83 driver. The LM90 is a sensor chip made by National * Semiconductor. It reports up to two temperatures (its own plus up to @@ -10,6 +10,17 @@ * obtained from National's website at: * http://www.national.com/pf/LM/LM90.html * + * This driver also supports the LM89 and LM99, two other sensor chips + * made by National Semiconductor. Both have an increased remote + * temperature measurement accuracy (1 degree), and the LM99 + * additionally shifts remote temperatures (measured and limits) by 16 + * degrees, which allows for higher temperatures measurement. The + * driver doesn't handle it since it can be done easily in user-space. + * Complete datasheets can be obtained from National's website at: + * http://www.national.com/pf/LM/LM89.html + * http://www.national.com/pf/LM/LM99.html + * Note that there is no way to differenciate between both chips. + * * This driver also supports the ADM1032, a sensor chip made by Analog * Devices. That chip is similar to the LM90, with a few differences * that are not handled by this driver. Complete datasheet can be @@ -45,9 +56,11 @@ /* * Addresses to scan * Address is fully defined internally and cannot be changed. + * LM89, LM90, LM99 and ADM1032 have address 0x4c. + * LM89-1, and LM99-1 have address 0x4d. */ -static unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END }; +static unsigned short normal_i2c[] = { 0x4c, 0x4d, I2C_CLIENT_END }; static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END }; static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END }; @@ -56,7 +69,7 @@ static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END }; * Insmod parameters */ -SENSORS_INSMOD_2(lm90, adm1032); +SENSORS_INSMOD_3(lm90, adm1032, lm99); /* * The LM90 registers @@ -261,7 +274,7 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); static int lm90_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, lm90_detect); } @@ -330,16 +343,26 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) LM90_REG_R_CHIP_ID); if (man_id == 0x01) { /* National Semiconductor */ - if (chip_id >= 0x21 && chip_id < 0x30 /* LM90 */ - && (kind == 0 /* skip detection */ - || ((i2c_smbus_read_byte_data(new_client, - LM90_REG_R_CONFIG2) & 0xF8) == 0x00 - && reg_convrate <= 0x09))) { - kind = lm90; + u8 reg_config2; + + reg_config2 = i2c_smbus_read_byte_data(new_client, + LM90_REG_R_CONFIG2); + + if (kind == 0 /* skip detection */ + || ((reg_config2 & 0xF8) == 0x00 + && reg_convrate <= 0x09)) { + if (address == 0x4C + && (chip_id & 0xF0) == 0x20) { /* LM90 */ + kind = lm90; + } else + if ((chip_id & 0xF0) == 0x30) { /* LM89/LM99 */ + kind = lm99; + } } - } - else if (man_id == 0x41) { /* Analog Devices */ - if ((chip_id & 0xF0) == 0x40 /* ADM1032 */ + } else + if (man_id == 0x41) { /* Analog Devices */ + if (address == 0x4C + && (chip_id & 0xF0) == 0x40 /* ADM1032 */ && (kind == 0 /* skip detection */ || (reg_config1 & 0x3F) == 0x00)) { kind = adm1032; @@ -358,6 +381,8 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind) name = "lm90"; } else if (kind == adm1032) { name = "adm1032"; + } else if (kind == lm99) { + name = "lm99"; } /* We can fill in the remaining client fields */ diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c new file mode 100644 index 000000000000..0fa55d45e6b6 --- /dev/null +++ b/drivers/i2c/chips/rtc8564.c @@ -0,0 +1,396 @@ +/* + * linux/drivers/i2c/chips/rtc8564.c + * + * Copyright (C) 2002-2004 Stefan Eletzhofer + * + * based on linux/drivers/acron/char/pcf8583.c + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Driver for system3's EPSON RTC 8564 chip + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/rtc.h> /* get the user-level API */ +#include <linux/init.h> +#include <linux/init.h> + +#include "rtc8564.h" + +#ifdef DEBUG +# define _DBG(x, fmt, args...) do{ if (debug>=x) printk(KERN_DEBUG"%s: " fmt "\n", __FUNCTION__, ##args); } while(0); +#else +# define _DBG(x, fmt, args...) do { } while(0); +#endif + +#define _DBGRTCTM(x, rtctm) if (debug>=x) printk("%s: secs=%d, mins=%d, hours=%d, mday=%d, " \ + "mon=%d, year=%d, wday=%d VL=%d\n", __FUNCTION__, \ + (rtctm).secs, (rtctm).mins, (rtctm).hours, (rtctm).mday, \ + (rtctm).mon, (rtctm).year, (rtctm).wday, (rtctm).vl); + +struct rtc8564_data { + struct i2c_client client; + u16 ctrl; +}; + +static inline u8 _rtc8564_ctrl1(struct i2c_client *client) +{ + struct rtc8564_data *data = i2c_get_clientdata(client); + return data->ctrl & 0xff; +} +static inline u8 _rtc8564_ctrl2(struct i2c_client *client) +{ + struct rtc8564_data *data = i2c_get_clientdata(client); + return (data->ctrl & 0xff00) >> 8; +} + +#define CTRL1(c) _rtc8564_ctrl1(c) +#define CTRL2(c) _rtc8564_ctrl2(c) + +#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10) +#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10) + +static int debug = 0; +MODULE_PARM(debug, "i"); + +static struct i2c_driver rtc8564_driver; + +static unsigned short ignore[] = { I2C_CLIENT_END }; +static unsigned short normal_addr[] = { 0x51, I2C_CLIENT_END }; + +static struct i2c_client_address_data addr_data = { + .normal_i2c = normal_addr, + .normal_i2c_range = ignore, + .probe = ignore, + .probe_range = ignore, + .ignore = ignore, + .ignore_range = ignore, + .force = ignore, +}; + +static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem); +static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem); + +static int rtc8564_read(struct i2c_client *client, unsigned char adr, + unsigned char *buf, unsigned char len) +{ + int ret = -EIO; + unsigned char addr[1] = { adr }; + struct i2c_msg msgs[2] = { + {client->addr, 0, 1, addr}, + {client->addr, I2C_M_RD, len, buf} + }; + + _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, buf, len); + + if (!buf || !client) { + ret = -EINVAL; + goto done; + } + + ret = i2c_transfer(client->adapter, msgs, 2); + if (ret == 2) { + ret = 0; + } + +done: + return ret; +} + +static int rtc8564_write(struct i2c_client *client, unsigned char adr, + unsigned char *data, unsigned char len) +{ + int ret = 0; + unsigned char _data[16]; + struct i2c_msg wr; + int i; + + if (!client || !data || len > 15) { + ret = -EINVAL; + goto done; + } + + _DBG(1, "client=%p, adr=%d, buf=%p, len=%d", client, adr, data, len); + + _data[0] = adr; + for (i = 0; i < len; i++) { + _data[i + 1] = data[i]; + _DBG(5, "data[%d] = 0x%02x (%d)", i, data[i], data[i]); + } + + wr.addr = client->addr; + wr.flags = 0; + wr.len = len + 1; + wr.buf = _data; + + ret = i2c_transfer(client->adapter, &wr, 1); + if (ret == 1) { + ret = 0; + } + +done: + return ret; +} + +static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind) +{ + int ret; + struct i2c_client *new_client; + struct rtc8564_data *d; + unsigned char data[10]; + unsigned char ad[1] = { 0 }; + struct i2c_msg ctrl_wr[1] = { + {addr, 0, 2, data} + }; + struct i2c_msg ctrl_rd[2] = { + {addr, 0, 1, ad}, + {addr, I2C_M_RD, 2, data} + }; + + d = kmalloc(sizeof(struct rtc8564_data), GFP_KERNEL); + if (!d) { + ret = -ENOMEM; + goto done; + } + memset(d, 0, sizeof(struct rtc8564_data)); + new_client = &d->client; + + strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE); + i2c_set_clientdata(new_client, d); + new_client->id = rtc8564_driver.id; + new_client->flags = I2C_CLIENT_ALLOW_USE | I2C_DF_NOTIFY; + new_client->addr = addr; + new_client->adapter = adap; + new_client->driver = &rtc8564_driver; + + _DBG(1, "client=%p", new_client); + _DBG(1, "client.id=%d", new_client->id); + + /* init ctrl1 reg */ + data[0] = 0; + data[1] = 0; + ret = i2c_transfer(new_client->adapter, ctrl_wr, 1); + if (ret != 1) { + printk(KERN_INFO "rtc8564: cant init ctrl1\n"); + ret = -ENODEV; + goto done; + } + + /* read back ctrl1 and ctrl2 */ + ret = i2c_transfer(new_client->adapter, ctrl_rd, 2); + if (ret != 2) { + printk(KERN_INFO "rtc8564: cant read ctrl\n"); + ret = -ENODEV; + goto done; + } + + d->ctrl = data[0] | (data[1] << 8); + + _DBG(1, "RTC8564_REG_CTRL1=%02x, RTC8564_REG_CTRL2=%02x", + data[0], data[1]); + + ret = i2c_attach_client(new_client); +done: + if (ret) { + kfree(d); + } + return ret; +} + +static int rtc8564_probe(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &addr_data, rtc8564_attach); +} + +static int rtc8564_detach(struct i2c_client *client) +{ + i2c_detach_client(client); + kfree(i2c_get_clientdata(client)); + return 0; +} + +static int rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt) +{ + int ret = -EIO; + unsigned char buf[15]; + + _DBG(1, "client=%p, dt=%p", client, dt); + + if (!dt || !client) + return -EINVAL; + + memset(buf, 0, sizeof(buf)); + + ret = rtc8564_read(client, 0, buf, 15); + if (ret) + return ret; + + /* century stored in minute alarm reg */ + dt->year = BCD_TO_BIN(buf[RTC8564_REG_YEAR]); + dt->year += 100 * BCD_TO_BIN(buf[RTC8564_REG_AL_MIN] & 0x3f); + dt->mday = BCD_TO_BIN(buf[RTC8564_REG_DAY] & 0x3f); + dt->wday = BCD_TO_BIN(buf[RTC8564_REG_WDAY] & 7); + dt->mon = BCD_TO_BIN(buf[RTC8564_REG_MON_CENT] & 0x1f); + + dt->secs = BCD_TO_BIN(buf[RTC8564_REG_SEC] & 0x7f); + dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80; + dt->mins = BCD_TO_BIN(buf[RTC8564_REG_MIN] & 0x7f); + dt->hours = BCD_TO_BIN(buf[RTC8564_REG_HR] & 0x3f); + + _DBGRTCTM(2, *dt); + + return 0; +} + +static int +rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo) +{ + int ret, len = 5; + unsigned char buf[15]; + + _DBG(1, "client=%p, dt=%p", client, dt); + + if (!dt || !client) + return -EINVAL; + + _DBGRTCTM(2, *dt); + + buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP; + buf[RTC8564_REG_CTRL2] = CTRL2(client); + buf[RTC8564_REG_SEC] = BIN_TO_BCD(dt->secs); + buf[RTC8564_REG_MIN] = BIN_TO_BCD(dt->mins); + buf[RTC8564_REG_HR] = BIN_TO_BCD(dt->hours); + + if (datetoo) { + len += 5; + buf[RTC8564_REG_DAY] = BIN_TO_BCD(dt->mday); + buf[RTC8564_REG_WDAY] = BIN_TO_BCD(dt->wday); + buf[RTC8564_REG_MON_CENT] = BIN_TO_BCD(dt->mon) & 0x1f; + /* century stored in minute alarm reg */ + buf[RTC8564_REG_YEAR] = BIN_TO_BCD(dt->year % 100); + buf[RTC8564_REG_AL_MIN] = BIN_TO_BCD(dt->year / 100); + } + + ret = rtc8564_write(client, 0, buf, len); + if (ret) { + _DBG(1, "error writing data! %d", ret); + } + + buf[RTC8564_REG_CTRL1] = CTRL1(client); + ret = rtc8564_write(client, 0, buf, 1); + if (ret) { + _DBG(1, "error writing data! %d", ret); + } + + return ret; +} + +static int rtc8564_get_ctrl(struct i2c_client *client, unsigned int *ctrl) +{ + struct rtc8564_data *data = i2c_get_clientdata(client); + + if (!ctrl || !client) + return -1; + + *ctrl = data->ctrl; + return 0; +} + +static int rtc8564_set_ctrl(struct i2c_client *client, unsigned int *ctrl) +{ + struct rtc8564_data *data = i2c_get_clientdata(client); + unsigned char buf[2]; + + if (!ctrl || !client) + return -1; + + buf[0] = *ctrl & 0xff; + buf[1] = (*ctrl & 0xff00) >> 8; + data->ctrl = *ctrl; + + return rtc8564_write(client, 0, buf, 2); +} + +static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem) +{ + + if (!mem || !client) + return -EINVAL; + + return rtc8564_read(client, mem->loc, mem->data, mem->nr); +} + +static int rtc8564_write_mem(struct i2c_client *client, struct mem *mem) +{ + + if (!mem || !client) + return -EINVAL; + + return rtc8564_write(client, mem->loc, mem->data, mem->nr); +} + +static int +rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg) +{ + + _DBG(1, "cmd=%d", cmd); + + switch (cmd) { + case RTC_GETDATETIME: + return rtc8564_get_datetime(client, arg); + + case RTC_SETTIME: + return rtc8564_set_datetime(client, arg, 0); + + case RTC_SETDATETIME: + return rtc8564_set_datetime(client, arg, 1); + + case RTC_GETCTRL: + return rtc8564_get_ctrl(client, arg); + + case RTC_SETCTRL: + return rtc8564_set_ctrl(client, arg); + + case MEM_READ: + return rtc8564_read_mem(client, arg); + + case MEM_WRITE: + return rtc8564_write_mem(client, arg); + + default: + return -EINVAL; + } +} + +static struct i2c_driver rtc8564_driver = { + .owner = THIS_MODULE, + .name = "RTC8564", + .id = I2C_DRIVERID_RTC8564, + .flags = I2C_DF_NOTIFY, + .attach_adapter = rtc8564_probe, + .detach_client = rtc8564_detach, + .command = rtc8564_command +}; + +static __init int rtc8564_init(void) +{ + return i2c_add_driver(&rtc8564_driver); +} + +static __exit void rtc8564_exit(void) +{ + i2c_del_driver(&rtc8564_driver); +} + +MODULE_AUTHOR("Stefan Eletzhofer <Stefan.Eletzhofer@eletztrick.de>"); +MODULE_DESCRIPTION("EPSON RTC8564 Driver"); +MODULE_LICENSE("GPL"); + +module_init(rtc8564_init); +module_exit(rtc8564_exit); diff --git a/drivers/i2c/chips/rtc8564.h b/drivers/i2c/chips/rtc8564.h new file mode 100644 index 000000000000..e5342d10b8fa --- /dev/null +++ b/drivers/i2c/chips/rtc8564.h @@ -0,0 +1,78 @@ +/* + * linux/drivers/i2c/chips/rtc8564.h + * + * Copyright (C) 2002-2004 Stefan Eletzhofer + * + * based on linux/drivers/acron/char/pcf8583.h + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +struct rtc_tm { + unsigned char secs; + unsigned char mins; + unsigned char hours; + unsigned char mday; + unsigned char mon; + unsigned short year; /* xxxx 4 digits :) */ + unsigned char wday; + unsigned char vl; +}; + +struct mem { + unsigned int loc; + unsigned int nr; + unsigned char *data; +}; + +#define RTC_GETDATETIME 0 +#define RTC_SETTIME 1 +#define RTC_SETDATETIME 2 +#define RTC_GETCTRL 3 +#define RTC_SETCTRL 4 +#define MEM_READ 5 +#define MEM_WRITE 6 + +#define RTC8564_REG_CTRL1 0x0 /* T 0 S 0 | T 0 0 0 */ +#define RTC8564_REG_CTRL2 0x1 /* 0 0 0 TI/TP | AF TF AIE TIE */ +#define RTC8564_REG_SEC 0x2 /* VL 4 2 1 | 8 4 2 1 */ +#define RTC8564_REG_MIN 0x3 /* x 4 2 1 | 8 4 2 1 */ +#define RTC8564_REG_HR 0x4 /* x x 2 1 | 8 4 2 1 */ +#define RTC8564_REG_DAY 0x5 /* x x 2 1 | 8 4 2 1 */ +#define RTC8564_REG_WDAY 0x6 /* x x x x | x 4 2 1 */ +#define RTC8564_REG_MON_CENT 0x7 /* C x x 1 | 8 4 2 1 */ +#define RTC8564_REG_YEAR 0x8 /* 8 4 2 1 | 8 4 2 1 */ +#define RTC8564_REG_AL_MIN 0x9 /* AE 4 2 1 | 8 4 2 1 */ +#define RTC8564_REG_AL_HR 0xa /* AE 4 2 1 | 8 4 2 1 */ +#define RTC8564_REG_AL_DAY 0xb /* AE x 2 1 | 8 4 2 1 */ +#define RTC8564_REG_AL_WDAY 0xc /* AE x x x | x 4 2 1 */ +#define RTC8564_REG_CLKOUT 0xd /* FE x x x | x x FD1 FD0 */ +#define RTC8564_REG_TCTL 0xe /* TE x x x | x x FD1 FD0 */ +#define RTC8564_REG_TIMER 0xf /* 8 bit binary */ + +/* Control reg */ +#define RTC8564_CTRL1_TEST1 (1<<3) +#define RTC8564_CTRL1_STOP (1<<5) +#define RTC8564_CTRL1_TEST2 (1<<7) + +#define RTC8564_CTRL2_TIE (1<<0) +#define RTC8564_CTRL2_AIE (1<<1) +#define RTC8564_CTRL2_TF (1<<2) +#define RTC8564_CTRL2_AF (1<<3) +#define RTC8564_CTRL2_TI_TP (1<<4) + +/* CLKOUT frequencies */ +#define RTC8564_FD_32768HZ (0x0) +#define RTC8564_FD_1024HZ (0x1) +#define RTC8564_FD_32 (0x2) +#define RTC8564_FD_1HZ (0x3) + +/* Timer CTRL */ +#define RTC8564_TD_4096HZ (0x0) +#define RTC8564_TD_64HZ (0x1) +#define RTC8564_TD_1HZ (0x2) +#define RTC8564_TD_1_60HZ (0x3) + +#define I2C_DRIVERID_RTC8564 0xf000 diff --git a/drivers/i2c/chips/via686a.c b/drivers/i2c/chips/via686a.c index d3f14e965fed..a5ec359b0f6f 100644 --- a/drivers/i2c/chips/via686a.c +++ b/drivers/i2c/chips/via686a.c @@ -108,7 +108,7 @@ static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e }; #define VIA686A_TEMP_MODE_MASK 0x3F #define VIA686A_TEMP_MODE_CONTINUOUS (0x00) -/* Conversions. Rounding and limit checking is only done on the TO_REG +/* Conversions. Limit checking is only done on the TO_REG variants. ********* VOLTAGE CONVERSIONS (Bob Dougherty) ******** @@ -123,49 +123,41 @@ static const u8 reghyst[] = { 0x3a, 0x3e, 0x1e }; volts = (25*regVal+133)*factor regVal = (volts/factor-133)/25 (These conversions were contributed by Jonathan Teh Soon Yew - <j.teh@iname.com>) - - These get us close, but they don't completely agree with what my BIOS - says- they are all a bit low. But, it all we have to go on... */ + <j.teh@iname.com>) */ static inline u8 IN_TO_REG(long val, int inNum) { - /* to avoid floating point, we multiply everything by 100. - val is guaranteed to be positive, so we can achieve the effect of - rounding by (...*10+5)/10. Note that the *10 is hidden in the - /250 (which should really be /2500). - At the end, we need to /100 because we *100 everything and we need - to /10 because of the rounding thing, so we /1000. */ + /* To avoid floating point, we multiply constants by 10 (100 for +12V). + Rounding is done (120500 is actually 133000 - 12500). + Remember that val is expressed in 0.001V/bit, which is why we divide + by an additional 10000 (100000 for +12V): 1000 for val and 10 (100) + for the constants. */ if (inNum <= 1) return (u8) - SENSORS_LIMIT(((val * 210240 - 13300) / 250 + 5) / 1000, - 0, 255); + SENSORS_LIMIT((val * 21024 - 1205000) / 250000, 0, 255); else if (inNum == 2) return (u8) - SENSORS_LIMIT(((val * 157370 - 13300) / 250 + 5) / 1000, - 0, 255); + SENSORS_LIMIT((val * 15737 - 1205000) / 250000, 0, 255); else if (inNum == 3) return (u8) - SENSORS_LIMIT(((val * 101080 - 13300) / 250 + 5) / 1000, - 0, 255); + SENSORS_LIMIT((val * 10108 - 1205000) / 250000, 0, 255); else - return (u8) SENSORS_LIMIT(((val * 41714 - 13300) / 250 + 5) - / 1000, 0, 255); + return (u8) + SENSORS_LIMIT((val * 41714 - 12050000) / 2500000, 0, 255); } static inline long IN_FROM_REG(u8 val, int inNum) { - /* to avoid floating point, we multiply everything by 100. - val is guaranteed to be positive, so we can achieve the effect of - rounding by adding 0.5. Or, to avoid fp math, we do (...*10+5)/10. - We need to scale with *100 anyway, so no need to /100 at the end. */ + /* To avoid floating point, we multiply constants by 10 (100 for +12V). + We also multiply them by 1000 because we want 0.001V/bit for the + output value. Rounding is done. */ if (inNum <= 1) - return (long) (((250000 * val + 13300) / 210240 * 10 + 5) /10); + return (long) ((250000 * val + 1330000 + 21024 / 2) / 21024); else if (inNum == 2) - return (long) (((250000 * val + 13300) / 157370 * 10 + 5) /10); + return (long) ((250000 * val + 1330000 + 15737 / 2) / 15737); else if (inNum == 3) - return (long) (((250000 * val + 13300) / 101080 * 10 + 5) /10); + return (long) ((250000 * val + 1330000 + 10108 / 2) / 10108); else - return (long) (((250000 * val + 13300) / 41714 * 10 + 5) /10); + return (long) ((2500000 * val + 13300000 + 41714 / 2) / 41714); } /********* FAN RPM CONVERSIONS ********/ @@ -276,52 +268,31 @@ static const u8 viaLUT[] = 239, 240 }; -/* Converting temps to (8-bit) hyst and over registers - No interpolation here. Just check the limits and go. - The +5 effectively rounds off properly and the +50 is because - the temps start at -50 */ +/* Converting temps to (8-bit) hyst and over registers + No interpolation here. + The +50 is because the temps start at -50 */ static inline u8 TEMP_TO_REG(long val) { - return (u8) - SENSORS_LIMIT(viaLUT[((val <= -500) ? 0 : (val >= 1100) ? 160 : - ((val + 5) / 10 + 50))], 0, 255); + return viaLUT[val <= -50000 ? 0 : val >= 110000 ? 160 : + (val < 0 ? val - 500 : val + 500) / 1000 + 50]; } -/* for 8-bit temperature hyst and over registers - The temp values are already *10, so we don't need to do that. - But we _will_ round these off to the nearest degree with (...*10+5)/10 */ -#define TEMP_FROM_REG(val) ((tempLUT[(val)]*10+5)/10) +/* for 8-bit temperature hyst and over registers */ +#define TEMP_FROM_REG(val) (tempLUT[(val)] * 100) -/* for 10-bit temperature readings - You might _think_ this is too long to inline, but's it's really only - called once... */ +/* for 10-bit temperature readings */ static inline long TEMP_FROM_REG10(u16 val) { - /* the temp values are already *10, so we don't need to do that. */ - long temp; u16 eightBits = val >> 2; u16 twoBits = val & 3; - /* handle the extremes first (they won't interpolate well! ;-) */ - if (val == 0) - return (long) tempLUT[0]; - if (val == 1023) - return (long) tempLUT[255]; - - if (twoBits == 0) - return (long) tempLUT[eightBits]; - else { - /* do some interpolation by multipying the lower and upper - bounds by 25, 50 or 75, then /100. */ - temp = ((25 * (4 - twoBits)) * tempLUT[eightBits] - + (25 * twoBits) * tempLUT[eightBits + 1]); - /* increase the magnitude by 50 to achieve rounding. */ - if (temp > 0) - temp += 50; - else - temp -= 50; - return (temp / 100); - } + /* no interpolation for these */ + if (twoBits == 0 || eightBits == 255) + return TEMP_FROM_REG(eightBits); + + /* do some linear interpolation */ + return (tempLUT[eightBits] * (4 - twoBits) + + tempLUT[eightBits + 1] * twoBits) * 25; } #define ALARMS_FROM_REG(val) (val) @@ -375,24 +346,24 @@ static void via686a_init_client(struct i2c_client *client); /* 7 voltage sensors */ static ssize_t show_in(struct device *dev, char *buf, int nr) { struct via686a_data *data = via686a_update_device(dev); - return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr)*10 ); + return sprintf(buf, "%ld\n", IN_FROM_REG(data->in[nr], nr)); } static ssize_t show_in_min(struct device *dev, char *buf, int nr) { struct via686a_data *data = via686a_update_device(dev); - return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr)*10 ); + return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_min[nr], nr)); } static ssize_t show_in_max(struct device *dev, char *buf, int nr) { struct via686a_data *data = via686a_update_device(dev); - return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr)*10 ); + return sprintf(buf, "%ld\n", IN_FROM_REG(data->in_max[nr], nr)); } static ssize_t set_in_min(struct device *dev, const char *buf, size_t count, int nr) { struct i2c_client *client = to_i2c_client(dev); struct via686a_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10)/10; + unsigned long val = simple_strtoul(buf, NULL, 10); data->in_min[nr] = IN_TO_REG(val,nr); via686a_write_value(client, VIA686A_REG_IN_MIN(nr), data->in_min[nr]); @@ -402,7 +373,7 @@ static ssize_t set_in_max(struct device *dev, const char *buf, size_t count, int nr) { struct i2c_client *client = to_i2c_client(dev); struct via686a_data *data = i2c_get_clientdata(client); - unsigned long val = simple_strtoul(buf, NULL, 10)/10; + unsigned long val = simple_strtoul(buf, NULL, 10); data->in_max[nr] = IN_TO_REG(val,nr); via686a_write_value(client, VIA686A_REG_IN_MAX(nr), data->in_max[nr]); @@ -449,21 +420,21 @@ show_in_offset(4); /* 3 temperatures */ static ssize_t show_temp(struct device *dev, char *buf, int nr) { struct via686a_data *data = via686a_update_device(dev); - return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])*100 ); + return sprintf(buf, "%ld\n", TEMP_FROM_REG10(data->temp[nr])); } static ssize_t show_temp_over(struct device *dev, char *buf, int nr) { struct via686a_data *data = via686a_update_device(dev); - return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])*100); + return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_over[nr])); } static ssize_t show_temp_hyst(struct device *dev, char *buf, int nr) { struct via686a_data *data = via686a_update_device(dev); - return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])*100); + return sprintf(buf, "%ld\n", TEMP_FROM_REG(data->temp_hyst[nr])); } static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count, int nr) { struct i2c_client *client = to_i2c_client(dev); struct via686a_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10)/100; + int val = simple_strtol(buf, NULL, 10); data->temp_over[nr] = TEMP_TO_REG(val); via686a_write_value(client, VIA686A_REG_TEMP_OVER(nr), data->temp_over[nr]); return count; @@ -472,7 +443,7 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count, int nr) { struct i2c_client *client = to_i2c_client(dev); struct via686a_data *data = i2c_get_clientdata(client); - int val = simple_strtol(buf, NULL, 10)/100; + int val = simple_strtol(buf, NULL, 10); data->temp_hyst[nr] = TEMP_TO_REG(val); via686a_write_value(client, VIA686A_REG_TEMP_HYST(nr), data->temp_hyst[nr]); return count; @@ -602,7 +573,7 @@ static struct i2c_driver via686a_driver = { /* This is called when the module is loaded */ static int via686a_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, via686a_detect); } diff --git a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c index b2274c5b7848..ac378b54b1cd 100644 --- a/drivers/i2c/chips/w83781d.c +++ b/drivers/i2c/chips/w83781d.c @@ -183,8 +183,10 @@ FAN_TO_REG(long rpm, int div) #define ALARMS_FROM_REG(val) (val) #define PWM_FROM_REG(val) (val) #define PWM_TO_REG(val) (SENSORS_LIMIT((val),0,255)) -#define BEEP_MASK_FROM_REG(val) (val) -#define BEEP_MASK_TO_REG(val) ((val) & 0xffffff) +#define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \ + (val) ^ 0x7fff : (val)) +#define BEEP_MASK_TO_REG(val,type) ((type) == as99127f ? \ + (~(val)) & 0x7fff : (val) & 0xffffff) #define BEEP_ENABLE_TO_REG(val) ((val) ? 1 : 0) #define BEEP_ENABLE_FROM_REG(val) ((val) ? 1 : 0) @@ -539,14 +541,18 @@ static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL) #define device_create_file_alarms(client) \ device_create_file(&client->dev, &dev_attr_alarms); -#define show_beep_reg(REG, reg) \ -static ssize_t show_beep_##reg (struct device *dev, char *buf) \ -{ \ - struct w83781d_data *data = w83781d_update_device(dev); \ - return sprintf(buf,"%ld\n", (long)BEEP_##REG##_FROM_REG(data->beep_##reg)); \ +static ssize_t show_beep_mask (struct device *dev, char *buf) +{ + struct w83781d_data *data = w83781d_update_device(dev); + return sprintf(buf, "%ld\n", + (long)BEEP_MASK_FROM_REG(data->beep_mask, data->type)); +} +static ssize_t show_beep_enable (struct device *dev, char *buf) +{ + struct w83781d_data *data = w83781d_update_device(dev); + return sprintf(buf, "%ld\n", + (long)BEEP_ENABLE_FROM_REG(data->beep_enable)); } -show_beep_reg(ENABLE, enable); -show_beep_reg(MASK, mask); #define BEEP_ENABLE 0 /* Store beep_enable */ #define BEEP_MASK 1 /* Store beep_mask */ @@ -562,7 +568,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count, val = simple_strtoul(buf, NULL, 10); if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ - data->beep_mask = BEEP_MASK_TO_REG(val); + data->beep_mask = BEEP_MASK_TO_REG(val, data->type); w83781d_write_value(client, W83781D_REG_BEEP_INTS1, data->beep_mask & 0xff); @@ -905,7 +911,7 @@ device_create_file(&client->dev, &dev_attr_rt##offset); \ static int w83781d_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, w83781d_detect); } @@ -1330,7 +1336,13 @@ w83781d_detach_client(struct i2c_client *client) return err; } - kfree(i2c_get_clientdata(client)); + if (i2c_get_clientdata(client)==NULL) { + /* subclients */ + kfree(client); + } else { + /* main client */ + kfree(i2c_get_clientdata(client)); + } return 0; } diff --git a/drivers/i2c/chips/w83l785ts.c b/drivers/i2c/chips/w83l785ts.c index 0062d86f1f6e..bb7abd315c72 100644 --- a/drivers/i2c/chips/w83l785ts.c +++ b/drivers/i2c/chips/w83l785ts.c @@ -145,7 +145,7 @@ static DEVICE_ATTR(temp1_max, S_IRUGO, show_temp_over, NULL) static int w83l785ts_attach_adapter(struct i2c_adapter *adapter) { - if (!(adapter->class & I2C_ADAP_CLASS_SMBUS)) + if (!(adapter->class & I2C_CLASS_HWMON)) return 0; return i2c_detect(adapter, &addr_data, w83l785ts_detect); } diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index 1126ed9070b4..c7d68784d733 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -153,7 +153,7 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count) case PCI_DEVICE_ID_INTEL_82801EB_11: case PCI_DEVICE_ID_INTEL_82801E_11: case PCI_DEVICE_ID_INTEL_ESB_2: - case PCI_DEVICE_ID_INTEL_ICH6_2: + case PCI_DEVICE_ID_INTEL_ICH6_19: p += sprintf(p, "PIIX4 Ultra 100 "); break; case PCI_DEVICE_ID_INTEL_82372FB_1: @@ -292,7 +292,7 @@ static u8 piix_ratemask (ide_drive_t *drive) case PCI_DEVICE_ID_INTEL_82801DB_11: case PCI_DEVICE_ID_INTEL_82801EB_11: case PCI_DEVICE_ID_INTEL_ESB_2: - case PCI_DEVICE_ID_INTEL_ICH6_2: + case PCI_DEVICE_ID_INTEL_ICH6_19: mode = 3; break; /* UDMA 66 capable */ @@ -627,7 +627,7 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char case PCI_DEVICE_ID_INTEL_82801EB_11: case PCI_DEVICE_ID_INTEL_82801E_11: case PCI_DEVICE_ID_INTEL_ESB_2: - case PCI_DEVICE_ID_INTEL_ICH6_2: + case PCI_DEVICE_ID_INTEL_ICH6_19: { unsigned int extra = 0; pci_read_config_dword(dev, 0x54, &extra); @@ -804,7 +804,7 @@ static struct pci_device_id piix_pci_tbl[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18}, #endif /* !CONFIG_SCSI_SATA */ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19}, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_19, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 20}, { 0, }, }; MODULE_DEVICE_TABLE(pci, piix_pci_tbl); diff --git a/drivers/ide/pci/piix.h b/drivers/ide/pci/piix.h index bdf164a3120b..2cce7c080988 100644 --- a/drivers/ide/pci/piix.h +++ b/drivers/ide/pci/piix.h @@ -70,7 +70,7 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = { /* 17 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801DB_10, "ICH4"), /* 18 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_82801EB_1, "ICH5-SATA"), /* 19 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_ESB_2, "ICH5"), - /* 20 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_ICH6_2, "ICH6"), + /* 20 */ DECLARE_PIIX_DEV(PCI_DEVICE_ID_INTEL_ICH6_19, "ICH6"), { .vendor = 0, .device = 0, diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c index 3a84f9752d4c..efe605a113a1 100644 --- a/drivers/media/video/bt832.c +++ b/drivers/media/video/bt832.c @@ -197,7 +197,7 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, static int bt832_probe(struct i2c_adapter *adap) { - if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, bt832_attach); return 0; } diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index c5c38e1ff315..c07a0d9c0c08 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c @@ -108,8 +108,8 @@ static struct i2c_adapter bttv_i2c_adap_sw_template = { .inc_use = bttv_inc_use, .dec_use = bttv_dec_use, #endif -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, +#ifdef I2C_CLASS_TV_ANALOG + .class = I2C_CLASS_TV_ANALOG, #endif I2C_DEVNAME("bt848"), .id = I2C_HW_B_BT848, @@ -291,8 +291,8 @@ static struct i2c_adapter bttv_i2c_adap_hw_template = { .inc_use = bttv_inc_use, .dec_use = bttv_dec_use, #endif -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, +#ifdef I2C_CLASS_TV_ANALOG + .class = I2C_CLASS_TV_ANALOG, #endif I2C_DEVNAME("bt878"), .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */, diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index a1a269eab0e9..9396ec27c193 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c @@ -128,8 +128,8 @@ static struct i2c_adapter cx8800_i2c_adap_template = { .inc_use = cx8800_inc_use, .dec_use = cx8800_dec_use, #endif -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, +#ifdef I2C_CLASS_TV_ANALOG + .class = I2C_CLASS_TV_ANALOG, #endif I2C_DEVNAME("cx2388x"), .id = I2C_HW_B_BT848, diff --git a/drivers/media/video/dpc7146.c b/drivers/media/video/dpc7146.c index 86ca8a4385b7..7fb4ae734b70 100644 --- a/drivers/media/video/dpc7146.c +++ b/drivers/media/video/dpc7146.c @@ -106,7 +106,7 @@ static int dpc_probe(struct saa7146_dev* dev) video port pins should be enabled here ?! */ saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); - saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, I2C_ADAP_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480); + saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, I2C_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480); if(i2c_add_adapter(&dpc->i2c_adapter) < 0) { DEB_S(("cannot register i2c-device. skipping.\n")); kfree(dpc); diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c index 748ba676c431..885e504de0a1 100644 --- a/drivers/media/video/hexium_gemini.c +++ b/drivers/media/video/hexium_gemini.c @@ -250,7 +250,7 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d /* enable i2c-port pins */ saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); - saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, I2C_ADAP_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480); + saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, I2C_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480); if (i2c_add_adapter(&hexium->i2c_adapter) < 0) { DEB_S(("cannot register i2c-device. skipping.\n")); kfree(hexium); diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c index cdb82726c420..1a3bbb6d3950 100644 --- a/drivers/media/video/hexium_orion.c +++ b/drivers/media/video/hexium_orion.c @@ -237,7 +237,7 @@ static int hexium_probe(struct saa7146_dev *dev) saa7146_write(dev, DD1_STREAM_B, 0x00000000); saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, I2C_ADAP_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480); + saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, I2C_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480); if (i2c_add_adapter(&hexium->i2c_adapter) < 0) { DEB_S(("cannot register i2c-device. skipping.\n")); kfree(hexium); diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index 3576ba504168..e2ecf212ccfc 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c @@ -1353,8 +1353,8 @@ static int msp_detach(struct i2c_client *client) static int msp_probe(struct i2c_adapter *adap) { -#ifdef I2C_ADAP_CLASS_TV_ANALOG - if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) +#ifdef I2C_CLASS_TV_ANALOG + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, msp_attach); #else switch (adap->id) { diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index cad4049a35e6..4156c62346fc 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c @@ -223,7 +223,7 @@ static int mxb_probe(struct saa7146_dev* dev) video port pins should be enabled here ?! */ saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); - saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, I2C_ADAP_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480); + saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, I2C_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480); if(i2c_add_adapter(&mxb->i2c_adapter) < 0) { DEB_S(("cannot register i2c-device. skipping.\n")); kfree(mxb); diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index 715a7cc5fed3..eecc102dbeb7 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -143,7 +143,7 @@ static int saa5246a_attach(struct i2c_adapter *adap, int addr, int kind) */ static int saa5246a_probe(struct i2c_adapter *adap) { - if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, saa5246a_attach); return 0; } diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 5bcdc178afb6..d486fb7faf67 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -219,7 +219,7 @@ static int saa5249_attach(struct i2c_adapter *adap, int addr, int kind) static int saa5249_probe(struct i2c_adapter *adap) { - if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, saa5249_attach); return 0; } diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index 4e43ba879253..5202dcc5a0db 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c @@ -9,6 +9,9 @@ * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net> * - moved over to linux>=2.4.x i2c protocol (1/1/2003) * + * Changes by Michael Hunold <michael@mihu.de> + * - implemented DECODER_SET_GPIO, DECODER_INIT, DECODER_SET_VBI_BYPASS + * * 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 @@ -112,7 +115,7 @@ saa7111_write_block (struct i2c_client *client, u8 block_data[32]; msg.addr = client->addr; - msg.flags = client->flags; + msg.flags = 0; while (len >= 2) { msg.buf = (char *) block_data; msg.len = 0; @@ -142,6 +145,13 @@ saa7111_write_block (struct i2c_client *client, return ret; } +static int +saa7111_init_decoder (struct i2c_client *client, + struct video_decoder_init *init) +{ + return saa7111_write_block(client, init->data, init->len); +} + static inline int saa7111_read (struct i2c_client *client, u8 reg) @@ -151,7 +161,7 @@ saa7111_read (struct i2c_client *client, /* ----------------------------------------------------------------------- */ -static const unsigned char init[] = { +static const unsigned char saa7111_i2c_init[] = { 0x00, 0x00, /* 00 - ID byte */ 0x01, 0x00, /* 01 - reserved */ @@ -201,8 +211,18 @@ saa7111_command (struct i2c_client *client, switch (cmd) { case 0: - //saa7111_write_block(client, init, sizeof(init)); - break; + case DECODER_INIT: + { + struct video_decoder_init *init = arg; + if (NULL != init) + return saa7111_init_decoder(client, init); + else { + struct video_decoder_init vdi; + vdi.data = saa7111_i2c_init; + vdi.len = sizeof(saa7111_i2c_init); + return saa7111_init_decoder(client, &vdi); + } + } case DECODER_DUMP: { @@ -274,6 +294,32 @@ saa7111_command (struct i2c_client *client, } break; + case DECODER_SET_GPIO: + { + int *iarg = arg; + if (0 != *iarg) { + saa7111_write(client, 0x11, + (decoder->reg[0x11] | 0x80)); + } else { + saa7111_write(client, 0x11, + (decoder->reg[0x11] & 0x7f)); + } + break; + } + + case DECODER_SET_VBI_BYPASS: + { + int *iarg = arg; + if (0 != *iarg) { + saa7111_write(client, 0x13, + (decoder->reg[0x13] & 0xf0) | 0x0a); + } else { + saa7111_write(client, 0x13, + (decoder->reg[0x13] & 0xf0)); + } + break; + } + case DECODER_SET_NORM: { int *iarg = arg; @@ -465,6 +511,7 @@ saa7111_detect_client (struct i2c_adapter *adapter, int i; struct i2c_client *client; struct saa7111 *decoder; + struct video_decoder_init vdi; dprintk(1, KERN_INFO @@ -509,7 +556,9 @@ saa7111_detect_client (struct i2c_adapter *adapter, return i; } - i = saa7111_write_block(client, init, sizeof(init)); + vdi.data = saa7111_i2c_init; + vdi.len = sizeof(saa7111_i2c_init); + i = saa7111_init_decoder(client, &vdi); if (i < 0) { dprintk(1, KERN_ERR "%s_attach error: init status %d\n", I2C_NAME(client), i); diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index d52cecb58416..5ea367e0e78b 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -335,7 +335,7 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) static int saa6752hs_probe(struct i2c_adapter *adap) { - if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, saa6752hs_attach); return 0; diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index cc1aaaa941e5..61305cf18717 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -347,8 +347,8 @@ static struct i2c_adapter saa7134_adap_template = { .inc_use = inc_use, .dec_use = dec_use, #endif -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, +#ifdef I2C_CLASS_TV_ANALOG + .class = I2C_CLASS_TV_ANALOG, #endif I2C_DEVNAME("saa7134"), .id = I2C_ALGO_SAA7134, diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 015f2f5fe49d..4365d9485ff6 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -338,8 +338,8 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind) static int tda7432_probe(struct i2c_adapter *adap) { -#ifdef I2C_ADAP_CLASS_TV_ANALOG - if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) +#ifdef I2C_CLASS_TV_ANALOG + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tda7432_attach); #else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 8c7a57944a68..ae5fd316fba0 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -272,8 +272,8 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind) static int tda9875_probe(struct i2c_adapter *adap) { -#ifdef I2C_ADAP_CLASS_TV_ANALOG - if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) +#ifdef I2C_CLASS_TV_ANALOG + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tda9875_attach); #else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index aef701636aa8..ddc380e1a878 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -370,8 +370,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) static int tda9887_probe(struct i2c_adapter *adap) { -#ifdef I2C_ADAP_CLASS_TV_ANALOG - if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) +#ifdef I2C_CLASS_TV_ANALOG + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tda9887_attach); #else switch (adap->id) { diff --git a/drivers/media/video/tuner.c b/drivers/media/video/tuner.c index d1150b7ba7d8..ab7030447a34 100644 --- a/drivers/media/video/tuner.c +++ b/drivers/media/video/tuner.c @@ -1067,8 +1067,8 @@ static int tuner_probe(struct i2c_adapter *adap) } this_adap = 0; -#ifdef I2C_ADAP_CLASS_TV_ANALOG - if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) +#ifdef I2C_CLASS_TV_ANALOG + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tuner_attach); #else switch (adap->id) { diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index ce2588a2fcaf..bf5017a7766c 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1497,8 +1497,8 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) static int chip_probe(struct i2c_adapter *adap) { -#ifdef I2C_ADAP_CLASS_TV_ANALOG - if (adap->class & I2C_ADAP_CLASS_TV_ANALOG) +#ifdef I2C_CLASS_TV_ANALOG + if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, chip_attach); #else switch (adap->id) { diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c index 677eb1604ec2..f690126f0960 100644 --- a/drivers/media/video/tvmixer.c +++ b/drivers/media/video/tvmixer.c @@ -263,8 +263,8 @@ static int tvmixer_clients(struct i2c_client *client) struct video_audio va; int i,minor; -#ifdef I2C_ADAP_CLASS_TV_ANALOG - if (!(client->adapter->class & I2C_ADAP_CLASS_TV_ANALOG)) +#ifdef I2C_CLASS_TV_ANALOG + if (!(client->adapter->class & I2C_CLASS_TV_ANALOG)) return -1; #else /* TV card ??? */ diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index 107ed4c2241b..f81bf5987d42 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c @@ -1578,7 +1578,7 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam) static struct i2c_adapter adap = { .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_W9968CF, - .class = I2C_ADAP_CLASS_CAM_DIGITAL, + .class = I2C_CLASS_CAM_DIGITAL, .owner = THIS_MODULE, .client_register = w9968cf_i2c_attach_inform, .client_unregister = w9968cf_i2c_detach_inform, diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index e988edbcb5b8..591e7ad68d30 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -222,7 +222,7 @@ #define I2C_HW_B_OMAHA 0x14 /* Omaha I2C interface (ARM) */ #define I2C_HW_B_GUIDE 0x15 /* Guide bit-basher */ #define I2C_HW_B_IXP2000 0x16 /* GPIO on IXP2000 systems */ -#define I2C_HW_B_IXP425 0x17 /* GPIO on IXP425 systems */ +#define I2C_HW_B_IXP4XX 0x17 /* GPIO on IXP4XX systems */ #define I2C_HW_B_S3VIA 0x18 /* S3Via ProSavage adapter */ #define I2C_HW_B_ZR36067 0x19 /* Zoran-36057/36067 based boards */ diff --git a/include/linux/i2c.h b/include/linux/i2c.h index d1c69565d4dc..969044dd3f7f 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -113,6 +113,7 @@ struct i2c_driver { struct module *owner; char name[32]; int id; + unsigned int class; unsigned int flags; /* div., see below */ /* Notifies the driver that a new bus has appeared. This routine @@ -237,7 +238,6 @@ struct i2c_adapter { /* data fields that are valid for all devices */ struct semaphore bus_lock; struct semaphore clist_lock; - unsigned int flags;/* flags specifying div. data */ int timeout; int retries; @@ -286,12 +286,14 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data) /* Must equal I2C_M_TEN below */ /* i2c adapter classes (bitmask) */ -#define I2C_ADAP_CLASS_SMBUS (1<<0) /* lm_sensors, ... */ -#define I2C_ADAP_CLASS_TV_ANALOG (1<<1) /* bttv + friends */ -#define I2C_ADAP_CLASS_TV_DIGITAL (1<<2) /* dbv cards */ -#define I2C_ADAP_CLASS_DDC (1<<3) /* i2c-matroxfb ? */ -#define I2C_ADAP_CLASS_CAM_ANALOG (1<<4) /* camera with analog CCD */ -#define I2C_ADAP_CLASS_CAM_DIGITAL (1<<5) /* most webcams */ +#define I2C_CLASS_HWMON (1<<0) /* lm_sensors, ... */ +#define I2C_CLASS_TV_ANALOG (1<<1) /* bttv + friends */ +#define I2C_CLASS_TV_DIGITAL (1<<2) /* dvb cards */ +#define I2C_CLASS_DDC (1<<3) /* i2c-matroxfb ? */ +#define I2C_CLASS_CAM_ANALOG (1<<4) /* camera with analog CCD */ +#define I2C_CLASS_CAM_DIGITAL (1<<5) /* most webcams */ +#define I2C_CLASS_SOUND (1<<6) /* sound devices */ +#define I2C_CLASS_ALL (UINT_MAX) /* all of the above */ /* i2c_client_address_data is the struct for holding default client * addresses for a driver and for the parameters supplied on the diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 649aa4561c36..7e0623153c1d 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2059,7 +2059,6 @@ #define PCI_DEVICE_ID_INTEL_82801EB_7 0x24d7 #define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db #define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd -#define PCI_DEVICE_ID_INTEL_ESB_0 0x25a0 #define PCI_DEVICE_ID_INTEL_ESB_1 0x25a1 #define PCI_DEVICE_ID_INTEL_ESB_2 0x25a2 #define PCI_DEVICE_ID_INTEL_ESB_3 0x25a3 @@ -2085,8 +2084,24 @@ #define PCI_DEVICE_ID_INTEL_82875_IG 0x257b #define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 #define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 -#define PCI_DEVICE_ID_INTEL_ICH6_2 0x266f -#define PCI_DEVICE_ID_INTEL_ICH6_3 0x266e +#define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 +#define PCI_DEVICE_ID_INTEL_ICH6_3 0x2651 +#define PCI_DEVICE_ID_INTEL_ICH6_4 0x2652 +#define PCI_DEVICE_ID_INTEL_ICH6_5 0x2653 +#define PCI_DEVICE_ID_INTEL_ICH6_6 0x2658 +#define PCI_DEVICE_ID_INTEL_ICH6_7 0x2659 +#define PCI_DEVICE_ID_INTEL_ICH6_8 0x265a +#define PCI_DEVICE_ID_INTEL_ICH6_9 0x265b +#define PCI_DEVICE_ID_INTEL_ICH6_10 0x265c +#define PCI_DEVICE_ID_INTEL_ICH6_11 0x2660 +#define PCI_DEVICE_ID_INTEL_ICH6_12 0x2662 +#define PCI_DEVICE_ID_INTEL_ICH6_13 0x2664 +#define PCI_DEVICE_ID_INTEL_ICH6_14 0x2666 +#define PCI_DEVICE_ID_INTEL_ICH6_15 0x2668 +#define PCI_DEVICE_ID_INTEL_ICH6_16 0x266a +#define PCI_DEVICE_ID_INTEL_ICH6_17 0x266d +#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e +#define PCI_DEVICE_ID_INTEL_ICH6_19 0x266f #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 diff --git a/include/linux/video_decoder.h b/include/linux/video_decoder.h index 1302c7f44ec5..0e9e48b83e3b 100644 --- a/include/linux/video_decoder.h +++ b/include/linux/video_decoder.h @@ -22,6 +22,10 @@ DECODER_STATUS_GOOD, the others are just nice things to know. #define DECODER_STATUS_NTSC 8 /* auto detected */ #define DECODER_STATUS_SECAM 16 /* auto detected */ +struct video_decoder_init { + unsigned char len; + const unsigned char *data; +}; #define DECODER_GET_CAPABILITIES _IOR('d', 1, struct video_decoder_capability) #define DECODER_GET_STATUS _IOR('d', 2, int) @@ -30,6 +34,9 @@ DECODER_STATUS_GOOD, the others are just nice things to know. #define DECODER_SET_OUTPUT _IOW('d', 5, int) /* 0 <= output < #outputs */ #define DECODER_ENABLE_OUTPUT _IOW('d', 6, int) /* boolean output enable control */ #define DECODER_SET_PICTURE _IOW('d', 7, struct video_picture) +#define DECODER_SET_GPIO _IOW('d', 8, int) /* switch general purpose pin */ +#define DECODER_INIT _IOW('d', 9, struct video_decoder_init) /* init internal registers at once */ +#define DECODER_SET_VBI_BYPASS _IOW('d', 10, int) /* switch vbi bypass */ #define DECODER_DUMP _IO('d', 192) /* debug hook */ diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c index cb693b05c095..e88c54c840ac 100644 --- a/sound/oss/i810_audio.c +++ b/sound/oss/i810_audio.c @@ -120,8 +120,8 @@ #ifndef PCI_DEVICE_ID_INTEL_ICH5 #define PCI_DEVICE_ID_INTEL_ICH5 0x24d5 #endif -#ifndef PCI_DEVICE_ID_INTEL_ICH6_3 -#define PCI_DEVICE_ID_INTEL_ICH6_3 0x266e +#ifndef PCI_DEVICE_ID_INTEL_ICH6_18 +#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e #endif #ifndef PCI_DEVICE_ID_INTEL_440MX #define PCI_DEVICE_ID_INTEL_440MX 0x7195 @@ -351,7 +351,7 @@ static struct pci_device_id i810_pci_tbl [] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD8111}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH4}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_3, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH4}, {0,} @@ -2797,7 +2797,7 @@ static int i810_ac97_power_up_bus(struct i810_card *card) /* see i810_ac97_init for the next 7 lines (jsaw) */ inw(card->ac97base); if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4 || card->pci_id == PCI_DEVICE_ID_INTEL_ICH5 || - card->pci_id == PCI_DEVICE_ID_INTEL_ESB_5 || card->pci_id == PCI_DEVICE_ID_INTEL_ICH6_3) + card->pci_id == PCI_DEVICE_ID_INTEL_ESB_5 || card->pci_id == PCI_DEVICE_ID_INTEL_ICH6_18) && (card->use_mmio)) { primary_codec_id = (int) readl(card->iobase_mmio + SDM) & 0x3; printk(KERN_INFO "i810_audio: Primary codec has ID %d\n", @@ -2868,7 +2868,7 @@ static int __devinit i810_ac97_init(struct i810_card *card) last codec ID spoken to. */ if ((card->pci_id == PCI_DEVICE_ID_INTEL_ICH4 || card->pci_id == PCI_DEVICE_ID_INTEL_ICH5 || - card->pci_id == PCI_DEVICE_ID_INTEL_ESB_5 || card->pci_id == PCI_DEVICE_ID_INTEL_ICH6_3) + card->pci_id == PCI_DEVICE_ID_INTEL_ESB_5 || card->pci_id == PCI_DEVICE_ID_INTEL_ICH6_18) && (card->use_mmio)) { ac97_id = (int) readl(card->iobase_mmio + SDM) & 0x3; printk(KERN_INFO "i810_audio: Connection %d with codec id %d\n", |
