aboutsummaryrefslogtreecommitdiff
path: root/drivers/i2c/chips
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/chips')
-rw-r--r--drivers/i2c/chips/Kconfig142
-rw-r--r--drivers/i2c/chips/Makefile26
-rw-r--r--drivers/i2c/chips/at24.c582
-rw-r--r--drivers/i2c/chips/ds1682.c267
-rw-r--r--drivers/i2c/chips/eeprom.c257
-rw-r--r--drivers/i2c/chips/max6875.c246
-rw-r--r--drivers/i2c/chips/pca9539.c152
-rw-r--r--drivers/i2c/chips/pcf8574.c215
-rw-r--r--drivers/i2c/chips/pcf8575.c198
-rw-r--r--drivers/i2c/chips/pcf8591.c325
-rw-r--r--drivers/i2c/chips/tsl2550.c489
11 files changed, 0 insertions, 2899 deletions
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
deleted file mode 100644
index b9bef04b7be..00000000000
--- a/drivers/i2c/chips/Kconfig
+++ /dev/null
@@ -1,142 +0,0 @@
-#
-# Miscellaneous I2C chip drivers configuration
-#
-# *** DEPRECATED! Do not add new entries! See Makefile ***
-#
-
-menu "Miscellaneous I2C Chip support"
-
-config DS1682
- tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm"
- depends on EXPERIMENTAL
- help
- If you say yes here you get support for Dallas Semiconductor
- DS1682 Total Elapsed Time Recorder.
-
- This driver can also be built as a module. If so, the module
- will be called ds1682.
-
-config AT24
- tristate "EEPROMs from most vendors"
- depends on SYSFS && EXPERIMENTAL
- help
- Enable this driver to get read/write support to most I2C EEPROMs,
- after you configure the driver to know about each EEPROM on
- your target board. Use these generic chip names, instead of
- vendor-specific ones like at24c64 or 24lc02:
-
- 24c00, 24c01, 24c02, spd (readonly 24c02), 24c04, 24c08,
- 24c16, 24c32, 24c64, 24c128, 24c256, 24c512, 24c1024
-
- Unless you like data loss puzzles, always be sure that any chip
- you configure as a 24c32 (32 kbit) or larger is NOT really a
- 24c16 (16 kbit) or smaller, and vice versa. Marking the chip
- as read-only won't help recover from this. Also, if your chip
- has any software write-protect mechanism you may want to review the
- code to make sure this driver won't turn it on by accident.
-
- If you use this with an SMBus adapter instead of an I2C adapter,
- full functionality is not available. Only smaller devices are
- supported (24c16 and below, max 4 kByte).
-
- This driver can also be built as a module. If so, the module
- will be called at24.
-
-config SENSORS_EEPROM
- tristate "EEPROM reader"
- depends on EXPERIMENTAL
- help
- If you say yes here you get read-only access to the EEPROM data
- available on modern memory DIMMs and Sony Vaio laptops. Such
- EEPROMs could theoretically be available on other devices as well.
-
- This driver can also be built as a module. If so, the module
- will be called eeprom.
-
-config SENSORS_PCF8574
- tristate "Philips PCF8574 and PCF8574A (DEPRECATED)"
- depends on EXPERIMENTAL && GPIO_PCF857X = "n"
- default n
- help
- If you say yes here you get support for Philips PCF8574 and
- PCF8574A chips. These chips are 8-bit I/O expanders for the I2C bus.
-
- This driver can also be built as a module. If so, the module
- will be called pcf8574.
-
- This driver is deprecated and will be dropped soon. Use
- drivers/gpio/pcf857x.c instead.
-
- These devices are hard to detect and rarely found on mainstream
- hardware. If unsure, say N.
-
-config PCF8575
- tristate "Philips PCF8575 (DEPRECATED)"
- default n
- depends on GPIO_PCF857X = "n"
- help
- If you say yes here you get support for Philips PCF8575 chip.
- This chip is a 16-bit I/O expander for the I2C bus. Several other
- chip manufacturers sell equivalent chips, e.g. Texas Instruments.
-
- This driver can also be built as a module. If so, the module
- will be called pcf8575.
-
- This driver is deprecated and will be dropped soon. Use
- drivers/gpio/pcf857x.c instead.
-
- This device is hard to detect and is rarely found on mainstream
- hardware. If unsure, say N.
-
-config SENSORS_PCA9539
- tristate "Philips PCA9539 16-bit I/O port (DEPRECATED)"
- depends on EXPERIMENTAL && GPIO_PCA953X = "n"
- help
- If you say yes here you get support for the Philips PCA9539
- 16-bit I/O port.
-
- This driver can also be built as a module. If so, the module
- will be called pca9539.
-
- This driver is deprecated and will be dropped soon. Use
- drivers/gpio/pca953x.c instead.
-
-config SENSORS_PCF8591
- tristate "Philips PCF8591"
- depends on EXPERIMENTAL
- default n
- help
- If you say yes here you get support for Philips PCF8591 chips.
-
- This driver can also be built as a module. If so, the module
- will be called pcf8591.
-
- These devices are hard to detect and rarely found on mainstream
- hardware. If unsure, say N.
-
-config SENSORS_MAX6875
- tristate "Maxim MAX6875 Power supply supervisor"
- depends on EXPERIMENTAL
- help
- If you say yes here you get support for the Maxim MAX6875
- EEPROM-programmable, quad power-supply sequencer/supervisor.
-
- This provides an interface to program the EEPROM and reset the chip.
-
- This driver also supports the Maxim MAX6874 hex power-supply
- sequencer/supervisor if found at a compatible address.
-
- This driver can also be built as a module. If so, the module
- will be called max6875.
-
-config SENSORS_TSL2550
- tristate "Taos TSL2550 ambient light sensor"
- depends on EXPERIMENTAL
- help
- If you say yes here you get support for the Taos TSL2550
- ambient light sensor.
-
- This driver can also be built as a module. If so, the module
- will be called tsl2550.
-
-endmenu
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
deleted file mode 100644
index 00fcb5193ac..00000000000
--- a/drivers/i2c/chips/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Makefile for miscellaneous I2C chip drivers.
-#
-# Do not add new drivers to this directory! It is DEPRECATED.
-#
-# Device drivers are better grouped according to the functionality they
-# implement rather than to the bus they are connected to. In particular:
-# * Hardware monitoring chip drivers go to drivers/hwmon
-# * RTC chip drivers go to drivers/rtc
-# * I/O expander drivers go to drivers/gpio
-#
-
-obj-$(CONFIG_DS1682) += ds1682.o
-obj-$(CONFIG_AT24) += at24.o
-obj-$(CONFIG_SENSORS_EEPROM) += eeprom.o
-obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
-obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
-obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
-obj-$(CONFIG_PCF8575) += pcf8575.o
-obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
-obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
-
-ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
-
diff --git a/drivers/i2c/chips/at24.c b/drivers/i2c/chips/at24.c
deleted file mode 100644
index d4775528abc..00000000000
--- a/drivers/i2c/chips/at24.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * at24.c - handle most I2C EEPROMs
- *
- * Copyright (C) 2005-2007 David Brownell
- * Copyright (C) 2008 Wolfram Sang, Pengutronix
- *
- * 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.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/sysfs.h>
-#include <linux/mod_devicetable.h>
-#include <linux/log2.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
-
-/*
- * I2C EEPROMs from most vendors are inexpensive and mostly interchangeable.
- * Differences between different vendor product lines (like Atmel AT24C or
- * MicroChip 24LC, etc) won't much matter for typical read/write access.
- * There are also I2C RAM chips, likewise interchangeable. One example
- * would be the PCF8570, which acts like a 24c02 EEPROM (256 bytes).
- *
- * However, misconfiguration can lose data. "Set 16-bit memory address"
- * to a part with 8-bit addressing will overwrite data. Writing with too
- * big a page size also loses data. And it's not safe to assume that the
- * conventional addresses 0x50..0x57 only hold eeproms; a PCF8563 RTC
- * uses 0x51, for just one example.
- *
- * Accordingly, explicit board-specific configuration data should be used
- * in almost all cases. (One partial exception is an SMBus used to access
- * "SPD" data for DRAM sticks. Those only use 24c02 EEPROMs.)
- *
- * So this driver uses "new style" I2C driver binding, expecting to be
- * told what devices exist. That may be in arch/X/mach-Y/board-Z.c or
- * similar kernel-resident tables; or, configuration data coming from
- * a bootloader.
- *
- * Other than binding model, current differences from "eeprom" driver are
- * that this one handles write access and isn't restricted to 24c02 devices.
- * It also handles larger devices (32 kbit and up) with two-byte addresses,
- * which won't work on pure SMBus systems.
- */
-
-struct at24_data {
- struct at24_platform_data chip;
- bool use_smbus;
-
- /*
- * Lock protects against activities from other Linux tasks,
- * but not from changes by other I2C masters.
- */
- struct mutex lock;
- struct bin_attribute bin;
-
- u8 *writebuf;
- unsigned write_max;
- unsigned num_addresses;
-
- /*
- * Some chips tie up multiple I2C addresses; dummy devices reserve
- * them for us, and we'll use them with SMBus calls.
- */
- struct i2c_client *client[];
-};
-
-/*
- * This parameter is to help this driver avoid blocking other drivers out
- * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C
- * clock, one 256 byte read takes about 1/43 second which is excessive;
- * but the 1/170 second it takes at 400 kHz may be quite reasonable; and
- * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible.
- *
- * This value is forced to be a power of two so that writes align on pages.
- */
-static unsigned io_limit = 128;
-module_param(io_limit, uint, 0);
-MODULE_PARM_DESC(io_limit, "Maximum bytes per I/O (default 128)");
-
-/*
- * Specs often allow 5 msec for a page write, sometimes 20 msec;
- * it's important to recover from write timeouts.
- */
-static unsigned write_timeout = 25;
-module_param(write_timeout, uint, 0);
-MODULE_PARM_DESC(write_timeout, "Time (in ms) to try writes (default 25)");
-
-#define AT24_SIZE_BYTELEN 5
-#define AT24_SIZE_FLAGS 8
-
-#define AT24_BITMASK(x) (BIT(x) - 1)
-
-/* create non-zero magic value for given eeprom parameters */
-#define AT24_DEVICE_MAGIC(_len, _flags) \
- ((1 << AT24_SIZE_FLAGS | (_flags)) \
- << AT24_SIZE_BYTELEN | ilog2(_len))
-
-static const struct i2c_device_id at24_ids[] = {
- /* needs 8 addresses as A0-A2 are ignored */
- { "24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) },
- /* old variants can't be handled with this generic entry! */
- { "24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) },
- { "24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) },
- /* spd is a 24c02 in memory DIMMs */
- { "spd", AT24_DEVICE_MAGIC(2048 / 8,
- AT24_FLAG_READONLY | AT24_FLAG_IRUGO) },
- { "24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },
- /* 24rf08 quirk is handled at i2c-core */
- { "24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) },
- { "24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },
- { "24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) },
- { "24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) },
- { "24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) },
- { "24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) },
- { "24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) },
- { "24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16) },
- { "at24", 0 },
- { /* END OF LIST */ }
-};
-MODULE_DEVICE_TABLE(i2c, at24_ids);
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * This routine supports chips which consume multiple I2C addresses. It
- * computes the addressing information to be used for a given r/w request.
- * Assumes that sanity checks for offset happened at sysfs-layer.
- */
-static struct i2c_client *at24_translate_offset(struct at24_data *at24,
- unsigned *offset)
-{
- unsigned i;
-
- if (at24->chip.flags & AT24_FLAG_ADDR16) {
- i = *offset >> 16;
- *offset &= 0xffff;
- } else {
- i = *offset >> 8;
- *offset &= 0xff;
- }
-
- return at24->client[i];
-}
-
-static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
- unsigned offset, size_t count)
-{
- struct i2c_msg msg[2];
- u8 msgbuf[2];
- struct i2c_client *client;
- int status, i;
-
- memset(msg, 0, sizeof(msg));
-
- /*
- * REVISIT some multi-address chips don't rollover page reads to
- * the next slave address, so we may need to truncate the count.
- * Those chips might need another quirk flag.
- *
- * If the real hardware used four adjacent 24c02 chips and that
- * were misconfigured as one 24c08, that would be a similar effect:
- * one "eeprom" file not four, but larger reads would fail when
- * they crossed certain pages.
- */
-
- /*
- * Slave address and byte offset derive from the offset. Always
- * set the byte address; on a multi-master board, another master
- * may have changed the chip's "current" address pointer.
- */
- client = at24_translate_offset(at24, &offset);
-
- if (count > io_limit)
- count = io_limit;
-
- /* Smaller eeproms can work given some SMBus extension calls */
- if (at24->use_smbus) {
- if (count > I2C_SMBUS_BLOCK_MAX)
- count = I2C_SMBUS_BLOCK_MAX;
- status = i2c_smbus_read_i2c_block_data(client, offset,
- count, buf);
- dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n",
- count, offset, status);
- return (status < 0) ? -EIO : status;
- }
-
- /*
- * When we have a better choice than SMBus calls, use a combined
- * I2C message. Write address; then read up to io_limit data bytes.
- * Note that read page rollover helps us here (unlike writes).
- * msgbuf is u8 and will cast to our needs.
- */
- i = 0;
- if (at24->chip.flags & AT24_FLAG_ADDR16)
- msgbuf[i++] = offset >> 8;
- msgbuf[i++] = offset;
-
- msg[0].addr = client->addr;
- msg[0].buf = msgbuf;
- msg[0].len = i;
-
- msg[1].addr = client->addr;
- msg[1].flags = I2C_M_RD;
- msg[1].buf = buf;
- msg[1].len = count;
-
- status = i2c_transfer(client->adapter, msg, 2);
- dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n",
- count, offset, status);
-
- if (status == 2)
- return count;
- else if (status >= 0)
- return -EIO;
- else
- return status;
-}
-
-static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct at24_data *at24;
- ssize_t retval = 0;
-
- at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
-
- if (unlikely(!count))
- return count;
-
- /*
- * Read data from chip, protecting against concurrent updates
- * from this host, but not from other I2C masters.
- */
- mutex_lock(&at24->lock);
-
- while (count) {
- ssize_t status;
-
- status = at24_eeprom_read(at24, buf, off, count);
- if (status <= 0) {
- if (retval == 0)
- retval = status;
- break;
- }
- buf += status;
- off += status;
- count -= status;
- retval += status;
- }
-
- mutex_unlock(&at24->lock);
-
- return retval;
-}
-
-
-/*
- * REVISIT: export at24_bin{read,write}() to let other kernel code use
- * eeprom data. For example, it might hold a board's Ethernet address, or
- * board-specific calibration data generated on the manufacturing floor.
- */
-
-
-/*
- * Note that if the hardware write-protect pin is pulled high, the whole
- * chip is normally write protected. But there are plenty of product
- * variants here, including OTP fuses and partial chip protect.
- *
- * We only use page mode writes; the alternative is sloooow. This routine
- * writes at most one page.
- */
-static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
- unsigned offset, size_t count)
-{
- struct i2c_client *client;
- struct i2c_msg msg;
- ssize_t status;
- unsigned long timeout, write_time;
- unsigned next_page;
-
- /* Get corresponding I2C address and adjust offset */
- client = at24_translate_offset(at24, &offset);
-
- /* write_max is at most a page */
- if (count > at24->write_max)
- count = at24->write_max;
-
- /* Never roll over backwards, to the start of this page */
- next_page = roundup(offset + 1, at24->chip.page_size);
- if (offset + count > next_page)
- count = next_page - offset;
-
- /* If we'll use I2C calls for I/O, set up the message */
- if (!at24->use_smbus) {
- int i = 0;
-
- msg.addr = client->addr;
- msg.flags = 0;
-
- /* msg.buf is u8 and casts will mask the values */
- msg.buf = at24->writebuf;
- if (at24->chip.flags & AT24_FLAG_ADDR16)
- msg.buf[i++] = offset >> 8;
-
- msg.buf[i++] = offset;
- memcpy(&msg.buf[i], buf, count);
- msg.len = i + count;
- }
-
- /*
- * Writes fail if the previous one didn't complete yet. We may
- * loop a few times until this one succeeds, waiting at least
- * long enough for one entire page write to work.
- */
- timeout = jiffies + msecs_to_jiffies(write_timeout);
- do {
- write_time = jiffies;
- if (at24->use_smbus) {
- status = i2c_smbus_write_i2c_block_data(client,
- offset, count, buf);
- if (status == 0)
- status = count;
- } else {
- status = i2c_transfer(client->adapter, &msg, 1);
- if (status == 1)
- status = count;
- }
- dev_dbg(&client->dev, "write %zu@%d --> %zd (%ld)\n",
- count, offset, status, jiffies);
-
- if (status == count)
- return count;
-
- /* REVISIT: at HZ=100, this is sloooow */
- msleep(1);
- } while (time_before(write_time, timeout));
-
- return -ETIMEDOUT;
-}
-
-static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct at24_data *at24;
- ssize_t retval = 0;
-
- at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
-
- if (unlikely(!count))
- return count;
-
- /*
- * Write data to chip, protecting against concurrent updates
- * from this host, but not from other I2C masters.
- */
- mutex_lock(&at24->lock);
-
- while (count) {
- ssize_t status;
-
- status = at24_eeprom_write(at24, buf, off, count);
- if (status <= 0) {
- if (retval == 0)
- retval = status;
- break;
- }
- buf += status;
- off += status;
- count -= status;
- retval += status;
- }
-
- mutex_unlock(&at24->lock);
-
- return retval;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- struct at24_platform_data chip;
- bool writable;
- bool use_smbus = false;
- struct at24_data *at24;
- int err;
- unsigned i, num_addresses;
- kernel_ulong_t magic;
-
- if (client->dev.platform_data) {
- chip = *(struct at24_platform_data *)client->dev.platform_data;
- } else {
- if (!id->driver_data) {
- err = -ENODEV;
- goto err_out;
- }
- magic = id->driver_data;
- chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN));
- magic >>= AT24_SIZE_BYTELEN;
- chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS);
- /*
- * This is slow, but we can't know all eeproms, so we better
- * play safe. Specifying custom eeprom-types via platform_data
- * is recommended anyhow.
- */
- chip.page_size = 1;
- }
-
- if (!is_power_of_2(chip.byte_len))
- dev_warn(&client->dev,
- "byte_len looks suspicious (no power of 2)!\n");
- if (!is_power_of_2(chip.page_size))
- dev_warn(&client->dev,
- "page_size looks suspicious (no power of 2)!\n");
-
- /* Use I2C operations unless we're stuck with SMBus extensions. */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- if (chip.flags & AT24_FLAG_ADDR16) {
- err = -EPFNOSUPPORT;
- goto err_out;
- }
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
- err = -EPFNOSUPPORT;
- goto err_out;
- }
- use_smbus = true;
- }
-
- if (chip.flags & AT24_FLAG_TAKE8ADDR)
- num_addresses = 8;
- else
- num_addresses = DIV_ROUND_UP(chip.byte_len,
- (chip.flags & AT24_FLAG_ADDR16) ? 65536 : 256);
-
- at24 = kzalloc(sizeof(struct at24_data) +
- num_addresses * sizeof(struct i2c_client *), GFP_KERNEL);
- if (!at24) {
- err = -ENOMEM;
- goto err_out;
- }
-
- mutex_init(&at24->lock);
- at24->use_smbus = use_smbus;
- at24->chip = chip;
- at24->num_addresses = num_addresses;
-
- /*
- * Export the EEPROM bytes through sysfs, since that's convenient.
- * By default, only root should see the data (maybe passwords etc)
- */
- at24->bin.attr.name = "eeprom";
- at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR;
- at24->bin.read = at24_bin_read;
- at24->bin.size = chip.byte_len;
-
- writable = !(chip.flags & AT24_FLAG_READONLY);
- if (writable) {
- if (!use_smbus || i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) {
-
- unsigned write_max = chip.page_size;
-
- at24->bin.write = at24_bin_write;
- at24->bin.attr.mode |= S_IWUSR;
-
- if (write_max > io_limit)
- write_max = io_limit;
- if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX)
- write_max = I2C_SMBUS_BLOCK_MAX;
- at24->write_max = write_max;
-
- /* buffer (data + address at the beginning) */
- at24->writebuf = kmalloc(write_max + 2, GFP_KERNEL);
- if (!at24->writebuf) {
- err = -ENOMEM;
- goto err_struct;
- }
- } else {
- dev_warn(&client->dev,
- "cannot write due to controller restrictions.");
- }
- }
-
- at24->client[0] = client;
-
- /* use dummy devices for multiple-address chips */
- for (i = 1; i < num_addresses; i++) {
- at24->client[i] = i2c_new_dummy(client->adapter,
- client->addr + i);
- if (!at24->client[i]) {
- dev_err(&client->dev, "address 0x%02x unavailable\n",
- client->addr + i);
- err = -EADDRINUSE;
- goto err_clients;
- }
- }
-
- err = sysfs_create_bin_file(&client->dev.kobj, &at24->bin);
- if (err)
- goto err_clients;
-
- i2c_set_clientdata(client, at24);
-
- dev_info(&client->dev, "%zu byte %s EEPROM %s\n",
- at24->bin.size, client->name,
- writable ? "(writable)" : "(read-only)");
- dev_dbg(&client->dev,
- "page_size %d, num_addresses %d, write_max %d%s\n",
- chip.page_size, num_addresses,
- at24->write_max,
- use_smbus ? ", use_smbus" : "");
-
- return 0;
-
-err_clients:
- for (i = 1; i < num_addresses; i++)
- if (at24->client[i])
- i2c_unregister_device(at24->client[i]);
-
- kfree(at24->writebuf);
-err_struct:
- kfree(at24);
-err_out:
- dev_dbg(&client->dev, "probe error %d\n", err);
- return err;
-}
-
-static int __devexit at24_remove(struct i2c_client *client)
-{
- struct at24_data *at24;
- int i;
-
- at24 = i2c_get_clientdata(client);
- sysfs_remove_bin_file(&client->dev.kobj, &at24->bin);
-
- for (i = 1; i < at24->num_addresses; i++)
- i2c_unregister_device(at24->client[i]);
-
- kfree(at24->writebuf);
- kfree(at24);
- i2c_set_clientdata(client, NULL);
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static struct i2c_driver at24_driver = {
- .driver = {
- .name = "at24",
- .owner = THIS_MODULE,
- },
- .probe = at24_probe,
- .remove = __devexit_p(at24_remove),
- .id_table = at24_ids,
-};
-
-static int __init at24_init(void)
-{
- io_limit = rounddown_pow_of_two(io_limit);
- return i2c_add_driver(&at24_driver);
-}
-module_init(at24_init);
-
-static void __exit at24_exit(void)
-{
- i2c_del_driver(&at24_driver);
-}
-module_exit(at24_exit);
-
-MODULE_DESCRIPTION("Driver for most I2C EEPROMs");
-MODULE_AUTHOR("David Brownell and Wolfram Sang");
-MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c
deleted file mode 100644
index f3ee4a1abb7..00000000000
--- a/drivers/i2c/chips/ds1682.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Dallas Semiconductor DS1682 Elapsed Time Recorder device driver
- *
- * Written by: Grant Likely <grant.likely@secretlab.ca>
- *
- * Copyright (C) 2007 Secret Lab Technologies Ltd.
- *
- * 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.
- */
-
-/*
- * The DS1682 elapsed timer recorder is a simple device that implements
- * one elapsed time counter, one event counter, an alarm signal and 10
- * bytes of general purpose EEPROM.
- *
- * This driver provides access to the DS1682 counters and user data via
- * the sysfs. The following attributes are added to the device node:
- * elapsed_time (u32): Total elapsed event time in ms resolution
- * alarm_time (u32): When elapsed time exceeds the value in alarm_time,
- * then the alarm pin is asserted.
- * event_count (u16): number of times the event pin has gone low.
- * eeprom (u8[10]): general purpose EEPROM
- *
- * Counter registers and user data are both read/write unless the device
- * has been write protected. This driver does not support turning off write
- * protection. Once write protection is turned on, it is impossible to
- * turn it off again, so I have left the feature out of this driver to avoid
- * accidental enabling, but it is trivial to add write protect support.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/string.h>
-#include <linux/list.h>
-#include <linux/sysfs.h>
-#include <linux/ctype.h>
-#include <linux/hwmon-sysfs.h>
-
-/* Device registers */
-#define DS1682_REG_CONFIG 0x00
-#define DS1682_REG_ALARM 0x01
-#define DS1682_REG_ELAPSED 0x05
-#define DS1682_REG_EVT_CNTR 0x09
-#define DS1682_REG_EEPROM 0x0b
-#define DS1682_REG_RESET 0x1d
-#define DS1682_REG_WRITE_DISABLE 0x1e
-#define DS1682_REG_WRITE_MEM_DISABLE 0x1f
-
-#define DS1682_EEPROM_SIZE 10
-
-/*
- * Generic counter attributes
- */
-static ssize_t ds1682_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
- struct i2c_client *client = to_i2c_client(dev);
- __le32 val = 0;
- int rc;
-
- dev_dbg(dev, "ds1682_show() called on %s\n", attr->attr.name);
-
- /* Read the register */
- rc = i2c_smbus_read_i2c_block_data(client, sattr->index, sattr->nr,
- (u8 *) & val);
- if (rc < 0)
- return -EIO;
-
- /* Special case: the 32 bit regs are time values with 1/4s
- * resolution, scale them up to milliseconds */
- if (sattr->nr == 4)
- return sprintf(buf, "%llu\n",
- ((unsigned long long)le32_to_cpu(val)) * 250);
-
- /* Format the output string and return # of bytes */
- return sprintf(buf, "%li\n", (long)le32_to_cpu(val));
-}
-
-static ssize_t ds1682_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
- struct i2c_client *client = to_i2c_client(dev);
- char *endp;
- u64 val;
- __le32 val_le;
- int rc;
-
- dev_dbg(dev, "ds1682_store() called on %s\n", attr->attr.name);
-
- /* Decode input */
- val = simple_strtoull(buf, &endp, 0);
- if (buf == endp) {
- dev_dbg(dev, "input string not a number\n");
- return -EINVAL;
- }
-
- /* Special case: the 32 bit regs are time values with 1/4s
- * resolution, scale input down to quarter-seconds */
- if (sattr->nr == 4)
- do_div(val, 250);
-
- /* write out the value */
- val_le = cpu_to_le32(val);
- rc = i2c_smbus_write_i2c_block_data(client, sattr->index, sattr->nr,
- (u8 *) & val_le);
- if (rc < 0) {
- dev_err(dev, "register write failed; reg=0x%x, size=%i\n",
- sattr->index, sattr->nr);
- return -EIO;
- }
-
- return count;
-}
-
-/*
- * Simple register attributes
- */
-static SENSOR_DEVICE_ATTR_2(elapsed_time, S_IRUGO | S_IWUSR, ds1682_show,
- ds1682_store, 4, DS1682_REG_ELAPSED);
-static SENSOR_DEVICE_ATTR_2(alarm_time, S_IRUGO | S_IWUSR, ds1682_show,
- ds1682_store, 4, DS1682_REG_ALARM);
-static SENSOR_DEVICE_ATTR_2(event_count, S_IRUGO | S_IWUSR, ds1682_show,
- ds1682_store, 2, DS1682_REG_EVT_CNTR);
-
-static const struct attribute_group ds1682_group = {
- .attrs = (struct attribute *[]) {
- &sensor_dev_attr_elapsed_time.dev_attr.attr,
- &sensor_dev_attr_alarm_time.dev_attr.attr,
- &sensor_dev_attr_event_count.dev_attr.attr,
- NULL,
- },
-};
-
-/*
- * User data attribute
- */
-static ssize_t ds1682_eeprom_read(struct kobject *kobj, struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct i2c_client *client = kobj_to_i2c_client(kobj);
- int rc;
-
- dev_dbg(&client->dev, "ds1682_eeprom_read(p=%p, off=%lli, c=%zi)\n",
- buf, off, count);
-
- if (off >= DS1682_EEPROM_SIZE)
- return 0;
-
- if (off + count > DS1682_EEPROM_SIZE)
- count = DS1682_EEPROM_SIZE - off;
-
- rc = i2c_smbus_read_i2c_block_data(client, DS1682_REG_EEPROM + off,
- count, buf);
- if (rc < 0)
- return -EIO;
-
- return count;
-}
-
-static ssize_t ds1682_eeprom_write(struct kobject *kobj, struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct i2c_client *client = kobj_to_i2c_client(kobj);
-
- dev_dbg(&client->dev, "ds1682_eeprom_write(p=%p, off=%lli, c=%zi)\n",
- buf, off, count);
-
- if (off >= DS1682_EEPROM_SIZE)
- return -ENOSPC;
-
- if (off + count > DS1682_EEPROM_SIZE)
- count = DS1682_EEPROM_SIZE - off;
-
- /* Write out to the device */
- if (i2c_smbus_write_i2c_block_data(client, DS1682_REG_EEPROM + off,
- count, buf) < 0)
- return -EIO;
-
- return count;
-}
-
-static struct bin_attribute ds1682_eeprom_attr = {
- .attr = {
- .name = "eeprom",
- .mode = S_IRUGO | S_IWUSR,
- },
- .size = DS1682_EEPROM_SIZE,
- .read = ds1682_eeprom_read,
- .write = ds1682_eeprom_write,
-};
-
-/*
- * Called when a ds1682 device is matched with this driver
- */
-static int ds1682_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int rc;
-
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_I2C_BLOCK)) {
- dev_err(&client->dev, "i2c bus does not support the ds1682\n");
- rc = -ENODEV;
- goto exit;
- }
-
- rc = sysfs_create_group(&client->dev.kobj, &ds1682_group);
- if (rc)
- goto exit;
-
- rc = sysfs_create_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
- if (rc)
- goto exit_bin_attr;
-
- return 0;
-
- exit_bin_attr:
- sysfs_remove_group(&client->dev.kobj, &ds1682_group);
- exit:
- return rc;
-}
-
-static int ds1682_remove(struct i2c_client *client)
-{
- sysfs_remove_bin_file(&client->dev.kobj, &ds1682_eeprom_attr);
- sysfs_remove_group(&client->dev.kobj, &ds1682_group);
- return 0;
-}
-
-static const struct i2c_device_id ds1682_id[] = {
- { "ds1682", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ds1682_id);
-
-static struct i2c_driver ds1682_driver = {
- .driver = {
- .name = "ds1682",
- },
- .probe = ds1682_probe,
- .remove = ds1682_remove,
- .id_table = ds1682_id,
-};
-
-static int __init ds1682_init(void)
-{
- return i2c_add_driver(&ds1682_driver);
-}
-
-static void __exit ds1682_exit(void)
-{
- i2c_del_driver(&ds1682_driver);
-}
-
-MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
-MODULE_DESCRIPTION("DS1682 Elapsed Time Indicator driver");
-MODULE_LICENSE("GPL");
-
-module_init(ds1682_init);
-module_exit(ds1682_exit);
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c
deleted file mode 100644
index 2c27193aeaa..00000000000
--- a/drivers/i2c/chips/eeprom.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- Copyright (C) 1998, 1999 Frodo Looijaard <frodol@dds.nl> and
- Philip Edelbrock <phil@netroedge.com>
- Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
- Copyright (C) 2003 IBM Corp.
- Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
-
- 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.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54,
- 0x55, 0x56, 0x57, I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(eeprom);
-
-
-/* Size of EEPROM in bytes */
-#define EEPROM_SIZE 256
-
-/* possible types of eeprom devices */
-enum eeprom_nature {
- UNKNOWN,
- VAIO,
-};
-
-/* Each client has this additional data */
-struct eeprom_data {
- struct mutex update_lock;
- u8 valid; /* bitfield, bit!=0 if slice is valid */
- unsigned long last_updated[8]; /* In jiffies, 8 slices */
- u8 data[EEPROM_SIZE]; /* Register values */
- enum eeprom_nature nature;
-};
-
-
-static void eeprom_update_client(struct i2c_client *client, u8 slice)
-{
- struct eeprom_data *data = i2c_get_clientdata(client);
- int i;
-
- mutex_lock(&data->update_lock);
-
- if (!(data->valid & (1 << slice)) ||
- time_after(jiffies, data->last_updated[slice] + 300 * HZ)) {
- dev_dbg(&client->dev, "Starting eeprom update, slice %u\n", slice);
-
- if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
- for (i = slice << 5; i < (slice + 1) << 5; i += 32)
- if (i2c_smbus_read_i2c_block_data(client, i,
- 32, data->data + i)
- != 32)
- goto exit;
- } else {
- for (i = slice << 5; i < (slice + 1) << 5; i += 2) {
- int word = i2c_smbus_read_word_data(client, i);
- if (word < 0)
- goto exit;
- data->data[i] = word & 0xff;
- data->data[i + 1] = word >> 8;
- }
- }
- data->last_updated[slice] = jiffies;
- data->valid |= (1 << slice);
- }
-exit:
- mutex_unlock(&data->update_lock);
-}
-
-static ssize_t eeprom_read(struct kobject *kobj, struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
-{
- struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj));
- struct eeprom_data *data = i2c_get_clientdata(client);
- u8 slice;
-
- if (off > EEPROM_SIZE)
- return 0;
- if (off + count > EEPROM_SIZE)
- count = EEPROM_SIZE - off;
-
- /* Only refresh slices which contain requested bytes */
- for (slice = off >> 5; slice <= (off + count - 1) >> 5; slice++)
- eeprom_update_client(client, slice);
-
- /* Hide Vaio private settings to regular users:
- - BIOS passwords: bytes 0x00 to 0x0f
- - UUID: bytes 0x10 to 0x1f
- - Serial number: 0xc0 to 0xdf */
- if (data->nature == VAIO && !capable(CAP_SYS_ADMIN)) {
- int i;
-
- for (i = 0; i < count; i++) {
- if ((off + i <= 0x1f) ||
- (off + i >= 0xc0 && off + i <= 0xdf))
- buf[i] = 0;
- else
- buf[i] = data->data[off + i];
- }
- } else {
- memcpy(buf, &data->data[off], count);
- }
-
- return count;
-}
-
-static struct bin_attribute eeprom_attr = {
- .attr = {
- .name = "eeprom",
- .mode = S_IRUGO,
- },
- .size = EEPROM_SIZE,
- .read = eeprom_read,
-};
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int eeprom_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
-
- /* EDID EEPROMs are often 24C00 EEPROMs, which answer to all
- addresses 0x50-0x57, but we only care about 0x50. So decline
- attaching to addresses >= 0x51 on DDC buses */
- if (!(adapter->class & I2C_CLASS_SPD) && client->addr >= 0x51)
- return -ENODEV;
-
- /* There are four ways we can read the EEPROM data:
- (1) I2C block reads (faster, but unsupported by most adapters)
- (2) Word reads (128% overhead)
- (3) Consecutive byte reads (88% overhead, unsafe)
- (4) Regular byte data reads (265% overhead)
- The third and fourth methods are not implemented by this driver
- because all known adapters support one of the first two. */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_WORD_DATA)
- && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_I2C_BLOCK))
- return -ENODEV;
-
- strlcpy(info->type, "eeprom", I2C_NAME_SIZE);
-
- return 0;
-}
-
-static int eeprom_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adapter = client->adapter;
- struct eeprom_data *data;
- int err;
-
- if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
-
- memset(data->data, 0xff, EEPROM_SIZE);
- i2c_set_clientdata(client, data);
- mutex_init(&data->update_lock);
- data->nature = UNKNOWN;
-
- /* Detect the Vaio nature of EEPROMs.
- We use the "PCG-" or "VGN-" prefix as the signature. */
- if (client->addr == 0x57
- && i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
- char name[4];
-
- name[0] = i2c_smbus_read_byte_data(client, 0x80);
- name[1] = i2c_smbus_read_byte_data(client, 0x81);
- name[2] = i2c_smbus_read_byte_data(client, 0x82);
- name[3] = i2c_smbus_read_byte_data(client, 0x83);
-
- if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) {
- dev_info(&client->dev, "Vaio EEPROM detected, "
- "enabling privacy protection\n");
- data->nature = VAIO;
- }
- }
-
- /* create the sysfs eeprom file */
- err = sysfs_create_bin_file(&client->dev.kobj, &eeprom_attr);
- if (err)
- goto exit_kfree;
-
- return 0;
-
-exit_kfree:
- kfree(data);
-exit:
- return err;
-}
-
-static int eeprom_remove(struct i2c_client *client)
-{
- sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr);
- kfree(i2c_get_clientdata(client));
-
- return 0;
-}
-
-static const struct i2c_device_id eeprom_id[] = {
- { "eeprom", 0 },
- { }
-};
-
-static struct i2c_driver eeprom_driver = {
- .driver = {
- .name = "eeprom",
- },
- .probe = eeprom_probe,
- .remove = eeprom_remove,
- .id_table = eeprom_id,
-
- .class = I2C_CLASS_DDC | I2C_CLASS_SPD,
- .detect = eeprom_detect,
- .address_data = &addr_data,
-};
-
-static int __init eeprom_init(void)
-{
- return i2c_add_driver(&eeprom_driver);
-}
-
-static void __exit eeprom_exit(void)
-{
- i2c_del_driver(&eeprom_driver);
-}
-
-
-MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and "
- "Philip Edelbrock <phil@netroedge.com> and "
- "Greg Kroah-Hartman <greg@kroah.com>");
-MODULE_DESCRIPTION("I2C EEPROM driver");
-MODULE_LICENSE("GPL");
-
-module_init(eeprom_init);
-module_exit(eeprom_exit);
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c
deleted file mode 100644
index 033d9d81ec8..00000000000
--- a/drivers/i2c/chips/max6875.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- max6875.c - driver for MAX6874/MAX6875
-
- Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
-
- Based on i2c/chips/eeprom.c
-
- The MAX6875 has a bank of registers and two banks of EEPROM.
- Address ranges are defined as follows:
- * 0x0000 - 0x0046 = configuration registers
- * 0x8000 - 0x8046 = configuration EEPROM
- * 0x8100 - 0x82FF = user EEPROM
-
- This driver makes the user EEPROM available for read.
-
- The registers & config EEPROM should be accessed via i2c-dev.
-
- The MAX6875 ignores the lowest address bit, so each chip responds to
- two addresses - 0x50/0x51 and 0x52/0x53.
-
- Note that the MAX6875 uses i2c_smbus_write_byte_data() to set the read
- address, so this driver is destructive if loaded for the wrong EEPROM chip.
-
- 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; version 2 of the License.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-/* Do not scan - the MAX6875 access method will write to some EEPROM chips */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(max6875);
-
-/* The MAX6875 can only read/write 16 bytes at a time */
-#define SLICE_SIZE 16
-#define SLICE_BITS 4
-
-/* USER EEPROM is at addresses 0x8100 - 0x82FF */
-#define USER_EEPROM_BASE 0x8100
-#define USER_EEPROM_SIZE 0x0200
-#define USER_EEPROM_SLICES 32
-
-/* MAX6875 commands */
-#define MAX6875_CMD_BLK_READ 0x84
-
-/* Each client has this additional data */
-struct max6875_data {
- struct i2c_client *fake_client;
- struct mutex update_lock;
-
- u32 valid;
- u8 data[USER_EEPROM_SIZE];
- unsigned long last_updated[USER_EEPROM_SLICES];
-};
-
-static void max6875_update_slice(struct i2c_client *client, int slice)
-{
- struct max6875_data *data = i2c_get_clientdata(client);
- int i, j, addr;
- u8 *buf;
-
- if (slice >= USER_EEPROM_SLICES)
- return;
-
- mutex_lock(&data->update_lock);
-
- buf = &data->data[slice << SLICE_BITS];
-
- if (!(data->valid & (1 << slice)) ||
- time_after(jiffies, data->last_updated[slice])) {
-
- dev_dbg(&client->dev, "Starting update of slice %u\n", slice);
-
- data->valid &= ~(1 << slice);
-
- addr = USER_EEPROM_BASE + (slice << SLICE_BITS);
-
- /* select the eeprom address */
- if (i2c_smbus_write_byte_data(client, addr >> 8, addr & 0xFF)) {
- dev_err(&client->dev, "address set failed\n");
- goto exit_up;
- }
-
- if (i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
- if (i2c_smbus_read_i2c_block_data(client,
- MAX6875_CMD_BLK_READ,
- SLICE_SIZE,
- buf) != SLICE_SIZE) {
- goto exit_up;
- }
- } else {
- for (i = 0; i < SLICE_SIZE; i++) {
- j = i2c_smbus_read_byte(client);
- if (j < 0) {
- goto exit_up;
- }
- buf[i] = j;
- }
- }
- data->last_updated[slice] = jiffies;
- data->valid |= (1 << slice);
- }
-exit_up:
- mutex_unlock(&data->update_lock);
-}
-
-static ssize_t max6875_read(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
-{
- struct i2c_client *client = kobj_to_i2c_client(kobj);
- struct max6875_data *data = i2c_get_clientdata(client);
- int slice, max_slice;
-
- if (off > USER_EEPROM_SIZE)
- return 0;
-
- if (off + count > USER_EEPROM_SIZE)
- count = USER_EEPROM_SIZE - off;
-
- /* refresh slices which contain requested bytes */
- max_slice = (off + count - 1) >> SLICE_BITS;
- for (slice = (off >> SLICE_BITS); slice <= max_slice; slice++)
- max6875_update_slice(client, slice);
-
- memcpy(buf, &data->data[off], count);
-
- return count;
-}
-
-static struct bin_attribute user_eeprom_attr = {
- .attr = {
- .name = "eeprom",
- .mode = S_IRUGO,
- },
- .size = USER_EEPROM_SIZE,
- .read = max6875_read,
-};
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int max6875_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
- | I2C_FUNC_SMBUS_READ_BYTE))
- return -ENODEV;
-
- /* Only check even addresses */
- if (client->addr & 1)
- return -ENODEV;
-
- strlcpy(info->type, "max6875", I2C_NAME_SIZE);
-
- return 0;
-}
-
-static int max6875_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct max6875_data *data;
- int err;
-
- if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL)))
- return -ENOMEM;
-
- /* A fake client is created on the odd address */
- data->fake_client = i2c_new_dummy(client->adapter, client->addr + 1);
- if (!data->fake_client) {
- err = -ENOMEM;
- goto exit_kfree;
- }
-
- /* Init real i2c_client */
- i2c_set_clientdata(client, data);
- mutex_init(&data->update_lock);
-
- err = sysfs_create_bin_file(&client->dev.kobj, &user_eeprom_attr);
- if (err)
- goto exit_remove_fake;
-
- return 0;
-
-exit_remove_fake:
- i2c_unregister_device(data->fake_client);
-exit_kfree:
- kfree(data);
- return err;
-}
-
-static int max6875_remove(struct i2c_client *client)
-{
- struct max6875_data *data = i2c_get_clientdata(client);
-
- i2c_unregister_device(data->fake_client);
-
- sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
- kfree(data);
-
- return 0;
-}
-
-static const struct i2c_device_id max6875_id[] = {
- { "max6875", 0 },
- { }
-};
-
-static struct i2c_driver max6875_driver = {
- .driver = {
- .name = "max6875",
- },
- .probe = max6875_probe,
- .remove = max6875_remove,
- .id_table = max6875_id,
-
- .detect = max6875_detect,
- .address_data = &addr_data,
-};
-
-static int __init max6875_init(void)
-{
- return i2c_add_driver(&max6875_driver);
-}
-
-static void __exit max6875_exit(void)
-{
- i2c_del_driver(&max6875_driver);
-}
-
-
-MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
-MODULE_DESCRIPTION("MAX6875 driver");
-MODULE_LICENSE("GPL");
-
-module_init(max6875_init);
-module_exit(max6875_exit);
diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c
deleted file mode 100644
index 270de4e56a8..00000000000
--- a/drivers/i2c/chips/pca9539.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- pca9539.c - 16-bit I/O port with interrupt and reset
-
- Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
-
- 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; version 2 of the License.
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/hwmon-sysfs.h>
-
-/* Addresses to scan: none, device is not autodetected */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(pca9539);
-
-enum pca9539_cmd
-{
- PCA9539_INPUT_0 = 0,
- PCA9539_INPUT_1 = 1,
- PCA9539_OUTPUT_0 = 2,
- PCA9539_OUTPUT_1 = 3,
- PCA9539_INVERT_0 = 4,
- PCA9539_INVERT_1 = 5,
- PCA9539_DIRECTION_0 = 6,
- PCA9539_DIRECTION_1 = 7,
-};
-
-/* following are the sysfs callback functions */
-static ssize_t pca9539_show(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
- struct i2c_client *client = to_i2c_client(dev);
- return sprintf(buf, "%d\n", i2c_smbus_read_byte_data(client,
- psa->index));
-}
-
-static ssize_t pca9539_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
- struct i2c_client *client = to_i2c_client(dev);
- unsigned long val = simple_strtoul(buf, NULL, 0);
- if (val > 0xff)
- return -EINVAL;
- i2c_smbus_write_byte_data(client, psa->index, val);
- return count;
-}
-
-/* Define the device attributes */
-
-#define PCA9539_ENTRY_RO(name, cmd_idx) \
- static SENSOR_DEVICE_ATTR(name, S_IRUGO, pca9539_show, NULL, cmd_idx)
-
-#define PCA9539_ENTRY_RW(name, cmd_idx) \
- static SENSOR_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, pca9539_show, \
- pca9539_store, cmd_idx)
-
-PCA9539_ENTRY_RO(input0, PCA9539_INPUT_0);
-PCA9539_ENTRY_RO(input1, PCA9539_INPUT_1);
-PCA9539_ENTRY_RW(output0, PCA9539_OUTPUT_0);
-PCA9539_ENTRY_RW(output1, PCA9539_OUTPUT_1);
-PCA9539_ENTRY_RW(invert0, PCA9539_INVERT_0);
-PCA9539_ENTRY_RW(invert1, PCA9539_INVERT_1);
-PCA9539_ENTRY_RW(direction0, PCA9539_DIRECTION_0);
-PCA9539_ENTRY_RW(direction1, PCA9539_DIRECTION_1);
-
-static struct attribute *pca9539_attributes[] = {
- &sensor_dev_attr_input0.dev_attr.attr,
- &sensor_dev_attr_input1.dev_attr.attr,
- &sensor_dev_attr_output0.dev_attr.attr,
- &sensor_dev_attr_output1.dev_attr.attr,
- &sensor_dev_attr_invert0.dev_attr.attr,
- &sensor_dev_attr_invert1.dev_attr.attr,
- &sensor_dev_attr_direction0.dev_attr.attr,
- &sensor_dev_attr_direction1.dev_attr.attr,
- NULL
-};
-
-static struct attribute_group pca9539_defattr_group = {
- .attrs = pca9539_attributes,
-};
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int pca9539_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- strlcpy(info->type, "pca9539", I2C_NAME_SIZE);
-
- return 0;
-}
-
-static int pca9539_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- /* Register sysfs hooks */
- return sysfs_create_group(&client->dev.kobj,
- &pca9539_defattr_group);
-}
-
-static int pca9539_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &pca9539_defattr_group);
- return 0;
-}
-
-static const struct i2c_device_id pca9539_id[] = {
- { "pca9539", 0 },
- { }
-};
-
-static struct i2c_driver pca9539_driver = {
- .driver = {
- .name = "pca9539",
- },
- .probe = pca9539_probe,
- .remove = pca9539_remove,
- .id_table = pca9539_id,
-
- .detect = pca9539_detect,
- .address_data = &addr_data,
-};
-
-static int __init pca9539_init(void)
-{
- return i2c_add_driver(&pca9539_driver);
-}
-
-static void __exit pca9539_exit(void)
-{
- i2c_del_driver(&pca9539_driver);
-}
-
-MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>");
-MODULE_DESCRIPTION("PCA9539 driver");
-MODULE_LICENSE("GPL");
-
-module_init(pca9539_init);
-module_exit(pca9539_exit);
-
diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c
deleted file mode 100644
index 6ec309894c8..00000000000
--- a/drivers/i2c/chips/pcf8574.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- Copyright (c) 2000 Frodo Looijaard <frodol@dds.nl>,
- Philip Edelbrock <phil@netroedge.com>,
- Dan Eaton <dan.eaton@rocketlogix.com>
- Ported to Linux 2.6 by Aurelien Jarno <aurel32@debian.org> with
- the help of Jean Delvare <khali@linux-fr.org>
-
- 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.
-*/
-
-/* A few notes about the PCF8574:
-
-* The PCF8574 is an 8-bit I/O expander for the I2C bus produced by
- Philips Semiconductors. It is designed to provide a byte I2C
- interface to up to 8 separate devices.
-
-* The PCF8574 appears as a very simple SMBus device which can be
- read from or written to with SMBUS byte read/write accesses.
-
- --Dan
-
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-
-/* Addresses to scan: none, device can't be detected */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_2(pcf8574, pcf8574a);
-
-/* Each client has this additional data */
-struct pcf8574_data {
- int write; /* Remember last written value */
-};
-
-static void pcf8574_init_client(struct i2c_client *client);
-
-/* following are the sysfs callback functions */
-static ssize_t show_read(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- return sprintf(buf, "%u\n", i2c_smbus_read_byte(client));
-}
-
-static DEVICE_ATTR(read, S_IRUGO, show_read, NULL);
-
-static ssize_t show_write(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct pcf8574_data *data = i2c_get_clientdata(to_i2c_client(dev));
-
- if (data->write < 0)
- return data->write;
-
- return sprintf(buf, "%d\n", data->write);
-}
-
-static ssize_t set_write(struct device *dev, struct device_attribute *attr, const char *buf,
- size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct pcf8574_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10);
-
- if (val > 0xff)
- return -EINVAL;
-
- data->write = val;
- i2c_smbus_write_byte(client, data->write);
- return count;
-}
-
-static DEVICE_ATTR(write, S_IWUSR | S_IRUGO, show_write, set_write);
-
-static struct attribute *pcf8574_attributes[] = {
- &dev_attr_read.attr,
- &dev_attr_write.attr,
- NULL
-};
-
-static const struct attribute_group pcf8574_attr_group = {
- .attrs = pcf8574_attributes,
-};
-
-/*
- * Real code
- */
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int pcf8574_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
- const char *client_name;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
- return -ENODEV;
-
- /* Now, we would do the remaining detection. But the PCF8574 is plainly
- impossible to detect! Stupid chip. */
-
- /* Determine the chip type */
- if (kind <= 0) {
- if (client->addr >= 0x38 && client->addr <= 0x3f)
- kind = pcf8574a;
- else
- kind = pcf8574;
- }
-
- if (kind == pcf8574a)
- client_name = "pcf8574a";
- else
- client_name = "pcf8574";
- strlcpy(info->type, client_name, I2C_NAME_SIZE);
-
- return 0;
-}
-
-static int pcf8574_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct pcf8574_data *data;
- int err;
-
- data = kzalloc(sizeof(struct pcf8574_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
-
- i2c_set_clientdata(client, data);
-
- /* Initialize the PCF8574 chip */
- pcf8574_init_client(client);
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &pcf8574_attr_group);
- if (err)
- goto exit_free;
- return 0;
-
- exit_free:
- kfree(data);
- exit:
- return err;
-}
-
-static int pcf8574_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &pcf8574_attr_group);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-/* Called when we have found a new PCF8574. */
-static void pcf8574_init_client(struct i2c_client *client)
-{
- struct pcf8574_data *data = i2c_get_clientdata(client);
- data->write = -EAGAIN;
-}
-
-static const struct i2c_device_id pcf8574_id[] = {
- { "pcf8574", 0 },
- { "pcf8574a", 0 },
- { }
-};
-
-static struct i2c_driver pcf8574_driver = {
- .driver = {
- .name = "pcf8574",
- },
- .probe = pcf8574_probe,
- .remove = pcf8574_remove,
- .id_table = pcf8574_id,
-
- .detect = pcf8574_detect,
- .address_data = &addr_data,
-};
-
-static int __init pcf8574_init(void)
-{
- return i2c_add_driver(&pcf8574_driver);
-}
-
-static void __exit pcf8574_exit(void)
-{
- i2c_del_driver(&pcf8574_driver);
-}
-
-
-MODULE_AUTHOR
- ("Frodo Looijaard <frodol@dds.nl>, "
- "Philip Edelbrock <phil@netroedge.com>, "
- "Dan Eaton <dan.eaton@rocketlogix.com> "
- "and Aurelien Jarno <aurelien@aurel32.net>");
-MODULE_DESCRIPTION("PCF8574 driver");
-MODULE_LICENSE("GPL");
-
-module_init(pcf8574_init);
-module_exit(pcf8574_exit);
diff --git a/drivers/i2c/chips/pcf8575.c b/drivers/i2c/chips/pcf8575.c
deleted file mode 100644
index 07fd7cb3c57..00000000000
--- a/drivers/i2c/chips/pcf8575.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- pcf8575.c
-
- About the PCF8575 chip: the PCF8575 is a 16-bit I/O expander for the I2C bus
- produced by a.o. Philips Semiconductors.
-
- Copyright (C) 2006 Michael Hennerich, Analog Devices Inc.
- <hennerich@blackfin.uclinux.org>
- Based on pcf8574.c.
-
- Copyright (c) 2007 Bart Van Assche <bart.vanassche@gmail.com>.
- Ported this driver from ucLinux to the mainstream Linux kernel.
-
- 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.
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/slab.h> /* kzalloc() */
-#include <linux/sysfs.h> /* sysfs_create_group() */
-
-/* Addresses to scan: none, device can't be detected */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD;
-
-
-/* Each client has this additional data */
-struct pcf8575_data {
- int write; /* last written value, or error code */
-};
-
-/* following are the sysfs callback functions */
-static ssize_t show_read(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- u16 val;
- u8 iopin_state[2];
-
- i2c_master_recv(client, iopin_state, 2);
-
- val = iopin_state[0];
- val |= iopin_state[1] << 8;
-
- return sprintf(buf, "%u\n", val);
-}
-
-static DEVICE_ATTR(read, S_IRUGO, show_read, NULL);
-
-static ssize_t show_write(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct pcf8575_data *data = dev_get_drvdata(dev);
- if (data->write < 0)
- return data->write;
- return sprintf(buf, "%d\n", data->write);
-}
-
-static ssize_t set_write(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct pcf8575_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10);
- u8 iopin_state[2];
-
- if (val > 0xffff)
- return -EINVAL;
-
- data->write = val;
-
- iopin_state[0] = val & 0xFF;
- iopin_state[1] = val >> 8;
-
- i2c_master_send(client, iopin_state, 2);
-
- return count;
-}
-
-static DEVICE_ATTR(write, S_IWUSR | S_IRUGO, show_write, set_write);
-
-static struct attribute *pcf8575_attributes[] = {
- &dev_attr_read.attr,
- &dev_attr_write.attr,
- NULL
-};
-
-static const struct attribute_group pcf8575_attr_group = {
- .attrs = pcf8575_attributes,
-};
-
-/*
- * Real code
- */
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int pcf8575_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
- return -ENODEV;
-
- /* This is the place to detect whether the chip at the specified
- address really is a PCF8575 chip. However, there is no method known
- to detect whether an I2C chip is a PCF8575 or any other I2C chip. */
-
- strlcpy(info->type, "pcf8575", I2C_NAME_SIZE);
-
- return 0;
-}
-
-static int pcf8575_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct pcf8575_data *data;
- int err;
-
- data = kzalloc(sizeof(struct pcf8575_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
-
- i2c_set_clientdata(client, data);
- data->write = -EAGAIN;
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &pcf8575_attr_group);
- if (err)
- goto exit_free;
-
- return 0;
-
-exit_free:
- kfree(data);
-exit:
- return err;
-}
-
-static int pcf8575_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &pcf8575_attr_group);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-static const struct i2c_device_id pcf8575_id[] = {
- { "pcf8575", 0 },
- { }
-};
-
-static struct i2c_driver pcf8575_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "pcf8575",
- },
- .probe = pcf8575_probe,
- .remove = pcf8575_remove,
- .id_table = pcf8575_id,
-
- .detect = pcf8575_detect,
- .address_data = &addr_data,
-};
-
-static int __init pcf8575_init(void)
-{
- return i2c_add_driver(&pcf8575_driver);
-}
-
-static void __exit pcf8575_exit(void)
-{
- i2c_del_driver(&pcf8575_driver);
-}
-
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>, "
- "Bart Van Assche <bart.vanassche@gmail.com>");
-MODULE_DESCRIPTION("pcf8575 driver");
-MODULE_LICENSE("GPL");
-
-module_init(pcf8575_init);
-module_exit(pcf8575_exit);
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c
deleted file mode 100644
index 16ce3e19377..00000000000
--- a/drivers/i2c/chips/pcf8591.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net>
- Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
- the help of Jean Delvare <khali@linux-fr.org>
-
- 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.
-*/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-
-/* Addresses to scan */
-static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
- 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_1(pcf8591);
-
-static int input_mode;
-module_param(input_mode, int, 0);
-MODULE_PARM_DESC(input_mode,
- "Analog input mode:\n"
- " 0 = four single ended inputs\n"
- " 1 = three differential inputs\n"
- " 2 = single ended and differential mixed\n"
- " 3 = two differential inputs\n");
-
-/* The PCF8591 control byte
- 7 6 5 4 3 2 1 0
- | 0 |AOEF| AIP | 0 |AINC| AICH | */
-
-/* Analog Output Enable Flag (analog output active if 1) */
-#define PCF8591_CONTROL_AOEF 0x40
-
-/* Analog Input Programming
- 0x00 = four single ended inputs
- 0x10 = three differential inputs
- 0x20 = single ended and differential mixed
- 0x30 = two differential inputs */
-#define PCF8591_CONTROL_AIP_MASK 0x30
-
-/* Autoincrement Flag (switch on if 1) */
-#define PCF8591_CONTROL_AINC 0x04
-
-/* Channel selection
- 0x00 = channel 0
- 0x01 = channel 1
- 0x02 = channel 2
- 0x03 = channel 3 */
-#define PCF8591_CONTROL_AICH_MASK 0x03
-
-/* Initial values */
-#define PCF8591_INIT_CONTROL ((input_mode << 4) | PCF8591_CONTROL_AOEF)
-#define PCF8591_INIT_AOUT 0 /* DAC out = 0 */
-
-/* Conversions */
-#define REG_TO_SIGNED(reg) (((reg) & 0x80)?((reg) - 256):(reg))
-
-struct pcf8591_data {
- struct mutex update_lock;
-
- u8 control;
- u8 aout;
-};
-
-static void pcf8591_init_client(struct i2c_client *client);
-static int pcf8591_read_channel(struct device *dev, int channel);
-
-/* following are the sysfs callback functions */
-#define show_in_channel(channel) \
-static ssize_t show_in##channel##_input(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- return sprintf(buf, "%d\n", pcf8591_read_channel(dev, channel));\
-} \
-static DEVICE_ATTR(in##channel##_input, S_IRUGO, \
- show_in##channel##_input, NULL);
-
-show_in_channel(0);
-show_in_channel(1);
-show_in_channel(2);
-show_in_channel(3);
-
-static ssize_t show_out0_ouput(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
- return sprintf(buf, "%d\n", data->aout * 10);
-}
-
-static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- unsigned int value;
- struct i2c_client *client = to_i2c_client(dev);
- struct pcf8591_data *data = i2c_get_clientdata(client);
- if ((value = (simple_strtoul(buf, NULL, 10) + 5) / 10) <= 255) {
- data->aout = value;
- i2c_smbus_write_byte_data(client, data->control, data->aout);
- return count;
- }
- return -EINVAL;
-}
-
-static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,
- show_out0_ouput, set_out0_output);
-
-static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct pcf8591_data *data = i2c_get_clientdata(to_i2c_client(dev));
- return sprintf(buf, "%u\n", !(!(data->control & PCF8591_CONTROL_AOEF)));
-}
-
-static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct pcf8591_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10);
-
- mutex_lock(&data->update_lock);
- if (val)
- data->control |= PCF8591_CONTROL_AOEF;
- else
- data->control &= ~PCF8591_CONTROL_AOEF;
- i2c_smbus_write_byte(client, data->control);
- mutex_unlock(&data->update_lock);
- return count;
-}
-
-static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO,
- show_out0_enable, set_out0_enable);
-
-static struct attribute *pcf8591_attributes[] = {
- &dev_attr_out0_enable.attr,
- &dev_attr_out0_output.attr,
- &dev_attr_in0_input.attr,
- &dev_attr_in1_input.attr,
- NULL
-};
-
-static const struct attribute_group pcf8591_attr_group = {
- .attrs = pcf8591_attributes,
-};
-
-static struct attribute *pcf8591_attributes_opt[] = {
- &dev_attr_in2_input.attr,
- &dev_attr_in3_input.attr,
- NULL
-};
-
-static const struct attribute_group pcf8591_attr_group_opt = {
- .attrs = pcf8591_attributes_opt,
-};
-
-/*
- * Real code
- */
-
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int pcf8591_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info)
-{
- struct i2c_adapter *adapter = client->adapter;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE
- | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
- return -ENODEV;
-
- /* Now, we would do the remaining detection. But the PCF8591 is plainly
- impossible to detect! Stupid chip. */
-
- strlcpy(info->type, "pcf8591", I2C_NAME_SIZE);
-
- return 0;
-}
-
-static int pcf8591_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct pcf8591_data *data;
- int err;
-
- if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
-
- i2c_set_clientdata(client, data);
- mutex_init(&data->update_lock);
-
- /* Initialize the PCF8591 chip */
- pcf8591_init_client(client);
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &pcf8591_attr_group);
- if (err)
- goto exit_kfree;
-
- /* Register input2 if not in "two differential inputs" mode */
- if (input_mode != 3) {
- if ((err = device_create_file(&client->dev,
- &dev_attr_in2_input)))
- goto exit_sysfs_remove;
- }
-
- /* Register input3 only in "four single ended inputs" mode */
- if (input_mode == 0) {
- if ((err = device_create_file(&client->dev,
- &dev_attr_in3_input)))
- goto exit_sysfs_remove;
- }
-
- return 0;
-
-exit_sysfs_remove:
- sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
- sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
-exit_kfree:
- kfree(data);
-exit:
- return err;
-}
-
-static int pcf8591_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
- sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-/* Called when we have found a new PCF8591. */
-static void pcf8591_init_client(struct i2c_client *client)
-{
- struct pcf8591_data *data = i2c_get_clientdata(client);
- data->control = PCF8591_INIT_CONTROL;
- data->aout = PCF8591_INIT_AOUT;
-
- i2c_smbus_write_byte_data(client, data->control, data->aout);
-
- /* The first byte transmitted contains the conversion code of the
- previous read cycle. FLUSH IT! */
- i2c_smbus_read_byte(client);
-}
-
-static int pcf8591_read_channel(struct device *dev, int channel)
-{
- u8 value;
- struct i2c_client *client = to_i2c_client(dev);
- struct pcf8591_data *data = i2c_get_clientdata(client);
-
- mutex_lock(&data->update_lock);
-
- if ((data->control & PCF8591_CONTROL_AICH_MASK) != channel) {
- data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK)
- | channel;
- i2c_smbus_write_byte(client, data->control);
-
- /* The first byte transmitted contains the conversion code of
- the previous read cycle. FLUSH IT! */
- i2c_smbus_read_byte(client);
- }
- value = i2c_smbus_read_byte(client);
-
- mutex_unlock(&data->update_lock);
-
- if ((channel == 2 && input_mode == 2) ||
- (channel != 3 && (input_mode == 1 || input_mode == 3)))
- return (10 * REG_TO_SIGNED(value));
- else
- return (10 * value);
-}
-
-static const struct i2c_device_id pcf8591_id[] = {
- { "pcf8591", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, pcf8591_id);
-
-static struct i2c_driver pcf8591_driver = {
- .driver = {
- .name = "pcf8591",
- },
- .probe = pcf8591_probe,
- .remove = pcf8591_remove,
- .id_table = pcf8591_id,
-
- .class = I2C_CLASS_HWMON, /* Nearest choice */
- .detect = pcf8591_detect,
- .address_data = &addr_data,
-};
-
-static int __init pcf8591_init(void)
-{
- if (input_mode < 0 || input_mode > 3) {
- printk(KERN_WARNING "pcf8591: invalid input_mode (%d)\n",
- input_mode);
- input_mode = 0;
- }
- return i2c_add_driver(&pcf8591_driver);
-}
-
-static void __exit pcf8591_exit(void)
-{
- i2c_del_driver(&pcf8591_driver);
-}
-
-MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>");
-MODULE_DESCRIPTION("PCF8591 driver");
-MODULE_LICENSE("GPL");
-
-module_init(pcf8591_init);
-module_exit(pcf8591_exit);
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
deleted file mode 100644
index 1a9cc135219..00000000000
--- a/drivers/i2c/chips/tsl2550.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * tsl2550.c - Linux kernel modules for ambient light sensor
- *
- * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
- * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-
-#define TSL2550_DRV_NAME "tsl2550"
-#define DRIVER_VERSION "1.1.1"
-
-/*
- * Defines
- */
-
-#define TSL2550_POWER_DOWN 0x00
-#define TSL2550_POWER_UP 0x03
-#define TSL2550_STANDARD_RANGE 0x18
-#define TSL2550_EXTENDED_RANGE 0x1d
-#define TSL2550_READ_ADC0 0x43
-#define TSL2550_READ_ADC1 0x83
-
-/*
- * Structs
- */
-
-struct tsl2550_data {
- struct i2c_client *client;
- struct mutex update_lock;
-
- unsigned int power_state : 1;
- unsigned int operating_mode : 1;
-};
-
-/*
- * Global data
- */
-
-static const u8 TSL2550_MODE_RANGE[2] = {
- TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
-};
-
-/*
- * Management functions
- */
-
-static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
-
- int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
-
- data->operating_mode = mode;
-
- return ret;
-}
-
-static int tsl2550_set_power_state(struct i2c_client *client, int state)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
- int ret;
-
- if (state == 0)
- ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
- else {
- ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
-
- /* On power up we should reset operating mode also... */
- tsl2550_set_operating_mode(client, data->operating_mode);
- }
-
- data->power_state = state;
-
- return ret;
-}
-
-static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
-{
- unsigned long end;
- int loop = 0, ret = 0;
-
- /*
- * Read ADC channel waiting at most 400ms (see data sheet for further
- * info).
- * To avoid long busy wait we spin for few milliseconds then
- * start sleeping.
- */
- end = jiffies + msecs_to_jiffies(400);
- while (time_before(jiffies, end)) {
- i2c_smbus_write_byte(client, cmd);
-
- if (loop++ < 5)
- mdelay(1);
- else
- msleep(1);
-
- ret = i2c_smbus_read_byte(client);
- if (ret < 0)
- return ret;
- else if (ret & 0x0080)
- break;
- }
- if (!(ret & 0x80))
- return -EIO;
- return ret & 0x7f; /* remove the "valid" bit */
-}
-
-/*
- * LUX calculation
- */
-
-#define TSL2550_MAX_LUX 1846
-
-static const u8 ratio_lut[] = {
- 100, 100, 100, 100, 100, 100, 100, 100,
- 100, 100, 100, 100, 100, 100, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 98, 98, 98, 98, 98,
- 98, 98, 97, 97, 97, 97, 97, 96,
- 96, 96, 96, 95, 95, 95, 94, 94,
- 93, 93, 93, 92, 92, 91, 91, 90,
- 89, 89, 88, 87, 87, 86, 85, 84,
- 83, 82, 81, 80, 79, 78, 77, 75,
- 74, 73, 71, 69, 68, 66, 64, 62,
- 60, 58, 56, 54, 52, 49, 47, 44,
- 42, 41, 40, 40, 39, 39, 38, 38,
- 37, 37, 37, 36, 36, 36, 35, 35,
- 35, 35, 34, 34, 34, 34, 33, 33,
- 33, 33, 32, 32, 32, 32, 32, 31,
- 31, 31, 31, 31, 30, 30, 30, 30,
- 30,
-};
-
-static const u16 count_lut[] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 18, 20, 22, 24, 26, 28, 30,
- 32, 34, 36, 38, 40, 42, 44, 46,
- 49, 53, 57, 61, 65, 69, 73, 77,
- 81, 85, 89, 93, 97, 101, 105, 109,
- 115, 123, 131, 139, 147, 155, 163, 171,
- 179, 187, 195, 203, 211, 219, 227, 235,
- 247, 263, 279, 295, 311, 327, 343, 359,
- 375, 391, 407, 423, 439, 455, 471, 487,
- 511, 543, 575, 607, 639, 671, 703, 735,
- 767, 799, 831, 863, 895, 927, 959, 991,
- 1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
- 1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
- 2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
- 3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
-};
-
-/*
- * This function is described into Taos TSL2550 Designer's Notebook
- * pages 2, 3.
- */
-static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
-{
- unsigned int lux;
-
- /* Look up count from channel values */
- u16 c0 = count_lut[ch0];
- u16 c1 = count_lut[ch1];
-
- /*
- * Calculate ratio.
- * Note: the "128" is a scaling factor
- */
- u8 r = 128;
-
- /* Avoid division by 0 and count 1 cannot be greater than count 0 */
- if (c0 && (c1 <= c0))
- r = c1 * 128 / c0;
- else
- return -1;
-
- /* Calculate LUX */
- lux = ((c0 - c1) * ratio_lut[r]) / 256;
-
- /* LUX range check */
- return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
-}
-
-/*
- * SysFS support
- */
-
-static ssize_t tsl2550_show_power_state(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
-
- return sprintf(buf, "%u\n", data->power_state);
-}
-
-static ssize_t tsl2550_store_power_state(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct tsl2550_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10);
- int ret;
-
- if (val < 0 || val > 1)
- return -EINVAL;
-
- mutex_lock(&data->update_lock);
- ret = tsl2550_set_power_state(client, val);
- mutex_unlock(&data->update_lock);
-
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
- tsl2550_show_power_state, tsl2550_store_power_state);
-
-static ssize_t tsl2550_show_operating_mode(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
-
- return sprintf(buf, "%u\n", data->operating_mode);
-}
-
-static ssize_t tsl2550_store_operating_mode(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct tsl2550_data *data = i2c_get_clientdata(client);
- unsigned long val = simple_strtoul(buf, NULL, 10);
- int ret;
-
- if (val < 0 || val > 1)
- return -EINVAL;
-
- if (data->power_state == 0)
- return -EBUSY;
-
- mutex_lock(&data->update_lock);
- ret = tsl2550_set_operating_mode(client, val);
- mutex_unlock(&data->update_lock);
-
- if (ret < 0)
- return ret;
-
- return count;
-}
-
-static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
- tsl2550_show_operating_mode, tsl2550_store_operating_mode);
-
-static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
-{
- u8 ch0, ch1;
- int ret;
-
- ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
- if (ret < 0)
- return ret;
- ch0 = ret;
-
- mdelay(1);
-
- ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
- if (ret < 0)
- return ret;
- ch1 = ret;
-
- /* Do the job */
- ret = tsl2550_calculate_lux(ch0, ch1);
- if (ret < 0)
- return ret;
-
- return sprintf(buf, "%d\n", ret);
-}
-
-static ssize_t tsl2550_show_lux1_input(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct tsl2550_data *data = i2c_get_clientdata(client);
- int ret;
-
- /* No LUX data if not operational */
- if (!data->power_state)
- return -EBUSY;
-
- mutex_lock(&data->update_lock);
- ret = __tsl2550_show_lux(client, buf);
- mutex_unlock(&data->update_lock);
-
- return ret;
-}
-
-static DEVICE_ATTR(lux1_input, S_IRUGO,
- tsl2550_show_lux1_input, NULL);
-
-static struct attribute *tsl2550_attributes[] = {
- &dev_attr_power_state.attr,
- &dev_attr_operating_mode.attr,
- &dev_attr_lux1_input.attr,
- NULL
-};
-
-static const struct attribute_group tsl2550_attr_group = {
- .attrs = tsl2550_attributes,
-};
-
-/*
- * Initialization function
- */
-
-static int tsl2550_init_client(struct i2c_client *client)
-{
- struct tsl2550_data *data = i2c_get_clientdata(client);
- int err;
-
- /*
- * Probe the chip. To do so we try to power up the device and then to
- * read back the 0x03 code
- */
- err = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
- if (err < 0)
- return err;
- mdelay(1);
- if (i2c_smbus_read_byte(client) != TSL2550_POWER_UP)
- return -ENODEV;
- data->power_state = 1;
-
- /* Set the default operating mode */
- err = i2c_smbus_write_byte(client,
- TSL2550_MODE_RANGE[data->operating_mode]);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-/*
- * I2C init/probing/exit functions
- */
-
-static struct i2c_driver tsl2550_driver;
-static int __devinit tsl2550_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
- struct tsl2550_data *data;
- int *opmode, err = 0;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
- err = -EIO;
- goto exit;
- }
-
- data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
- data->client = client;
- i2c_set_clientdata(client, data);
-
- /* Check platform data */
- opmode = client->dev.platform_data;
- if (opmode) {
- if (*opmode < 0 || *opmode > 1) {
- dev_err(&client->dev, "invalid operating_mode (%d)\n",
- *opmode);
- err = -EINVAL;
- goto exit_kfree;
- }
- data->operating_mode = *opmode;
- } else
- data->operating_mode = 0; /* default mode is standard */
- dev_info(&client->dev, "%s operating mode\n",
- data->operating_mode ? "extended" : "standard");
-
- mutex_init(&data->update_lock);
-
- /* Initialize the TSL2550 chip */
- err = tsl2550_init_client(client);
- if (err)
- goto exit_kfree;
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
- if (err)
- goto exit_kfree;
-
- dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
-
- return 0;
-
-exit_kfree:
- kfree(data);
-exit:
- return err;
-}
-
-static int __devexit tsl2550_remove(struct i2c_client *client)
-{
- sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
-
- /* Power down the device */
- tsl2550_set_power_state(client, 0);
-
- kfree(i2c_get_clientdata(client));
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-
-static int tsl2550_suspend(struct i2c_client *client, pm_message_t mesg)
-{
- return tsl2550_set_power_state(client, 0);
-}
-
-static int tsl2550_resume(struct i2c_client *client)
-{
- return tsl2550_set_power_state(client, 1);
-}
-
-#else
-
-#define tsl2550_suspend NULL
-#define tsl2550_resume NULL
-
-#endif /* CONFIG_PM */
-
-static const struct i2c_device_id tsl2550_id[] = {
- { "tsl2550", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tsl2550_id);
-
-static struct i2c_driver tsl2550_driver = {
- .driver = {
- .name = TSL2550_DRV_NAME,
- .owner = THIS_MODULE,
- },
- .suspend = tsl2550_suspend,
- .resume = tsl2550_resume,
- .probe = tsl2550_probe,
- .remove = __devexit_p(tsl2550_remove),
- .id_table = tsl2550_id,
-};
-
-static int __init tsl2550_init(void)
-{
- return i2c_add_driver(&tsl2550_driver);
-}
-
-static void __exit tsl2550_exit(void)
-{
- i2c_del_driver(&tsl2550_driver);
-}
-
-MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
-MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRIVER_VERSION);
-
-module_init(tsl2550_init);
-module_exit(tsl2550_exit);