diff options
Diffstat (limited to 'drivers/i2c/chips')
| -rw-r--r-- | drivers/i2c/chips/Kconfig | 142 | ||||
| -rw-r--r-- | drivers/i2c/chips/Makefile | 26 | ||||
| -rw-r--r-- | drivers/i2c/chips/at24.c | 582 | ||||
| -rw-r--r-- | drivers/i2c/chips/ds1682.c | 267 | ||||
| -rw-r--r-- | drivers/i2c/chips/eeprom.c | 257 | ||||
| -rw-r--r-- | drivers/i2c/chips/max6875.c | 246 | ||||
| -rw-r--r-- | drivers/i2c/chips/pca9539.c | 152 | ||||
| -rw-r--r-- | drivers/i2c/chips/pcf8574.c | 215 | ||||
| -rw-r--r-- | drivers/i2c/chips/pcf8575.c | 198 | ||||
| -rw-r--r-- | drivers/i2c/chips/pcf8591.c | 325 | ||||
| -rw-r--r-- | drivers/i2c/chips/tsl2550.c | 489 |
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); |
