aboutsummaryrefslogtreecommitdiff
path: root/drivers/i2c/chips
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/chips')
-rw-r--r--drivers/i2c/chips/Kconfig141
-rw-r--r--drivers/i2c/chips/Makefile27
-rw-r--r--drivers/i2c/chips/ds1682.c260
-rw-r--r--drivers/i2c/chips/eeprom.c270
-rw-r--r--drivers/i2c/chips/isp1301_omap.c1650
-rw-r--r--drivers/i2c/chips/max6875.c273
-rw-r--r--drivers/i2c/chips/menelaus.c1278
-rw-r--r--drivers/i2c/chips/pca9539.c196
-rw-r--r--drivers/i2c/chips/pcf8574.c234
-rw-r--r--drivers/i2c/chips/pcf8575.c214
-rw-r--r--drivers/i2c/chips/pcf8591.c342
-rw-r--r--drivers/i2c/chips/tps65010.c969
-rw-r--r--drivers/i2c/chips/tsl2550.c481
13 files changed, 0 insertions, 6335 deletions
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
deleted file mode 100644
index b21593f9358..00000000000
--- a/drivers/i2c/chips/Kconfig
+++ /dev/null
@@ -1,141 +0,0 @@
-#
-# Miscellaneous I2C chip drivers configuration
-#
-
-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 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"
- depends on EXPERIMENTAL
- 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.
-
- These devices are hard to detect and rarely found on mainstream
- hardware. If unsure, say N.
-
-config PCF8575
- tristate "Philips PCF8575"
- default 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 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_PCA9539 = "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/pca9539.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 ISP1301_OMAP
- tristate "Philips ISP1301 with OMAP OTG"
- depends on ARCH_OMAP_OTG
- help
- If you say yes here you get support for the Philips ISP1301
- USB-On-The-Go transceiver working with the OMAP OTG controller.
- The ISP1301 is used in products including H2 and H3 development
- boards for Texas Instruments OMAP processors.
-
- This driver can also be built as a module. If so, the module
- will be called isp1301_omap.
-
-config TPS65010
- tristate "TPS6501x Power Management chips"
- default y if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_OSK
- help
- If you say yes here you get support for the TPS6501x series of
- Power Management chips. These include voltage regulators,
- lithium ion/polymer battery charging, and other features that
- are often used in portable devices like cell phones and cameras.
-
- This driver can also be built as a module. If so, the module
- will be called tps65010.
-
-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.
-
-config MENELAUS
- bool "TWL92330/Menelaus PM chip"
- depends on I2C=y && ARCH_OMAP24XX
- help
- If you say yes here you get support for the Texas Instruments
- TWL92330/Menelaus Power Management chip. This include voltage
- regulators, Dual slot memory card tranceivers, real-time clock
- and other features that are often used in portable devices like
- cell phones and PDAs.
-
-endmenu
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
deleted file mode 100644
index e47aca0ca5a..00000000000
--- a/drivers/i2c/chips/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Makefile for miscellaneous I2C chip drivers.
-#
-# Think twice before you add a new driver to this directory.
-# 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_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_ISP1301_OMAP) += isp1301_omap.o
-obj-$(CONFIG_TPS65010) += tps65010.o
-obj-$(CONFIG_MENELAUS) += menelaus.o
-obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
-
-ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
-EXTRA_CFLAGS += -DDEBUG
-endif
-
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c
deleted file mode 100644
index 9e94542c18a..00000000000
--- a/drivers/i2c/chips/ds1682.c
+++ /dev/null
@@ -1,260 +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,
- .owner = THIS_MODULE,
- },
- .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)
-{
- 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 struct i2c_driver ds1682_driver = {
- .driver = {
- .name = "ds1682",
- },
- .probe = ds1682_probe,
- .remove = ds1682_remove,
-};
-
-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 7dee001e513..00000000000
--- a/drivers/i2c/chips/eeprom.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- eeprom.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- 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.
-
- 2004-01-16 Jean Delvare <khali@linux-fr.org>
- Divide the eeprom in 32-byte (arbitrary) slices. This significantly
- speeds sensors up, as well as various scripts using the eeprom
- module.
-
- 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 i2c_client client;
- 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 int eeprom_attach_adapter(struct i2c_adapter *adapter);
-static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind);
-static int eeprom_detach_client(struct i2c_client *client);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver eeprom_driver = {
- .driver = {
- .name = "eeprom",
- },
- .attach_adapter = eeprom_attach_adapter,
- .detach_client = eeprom_detach_client,
-};
-
-static void eeprom_update_client(struct i2c_client *client, u8 slice)
-{
- struct eeprom_data *data = i2c_get_clientdata(client);
- int i, j;
-
- 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 {
- if (i2c_smbus_write_byte(client, slice << 5)) {
- dev_dbg(&client->dev, "eeprom read start has failed!\n");
- goto exit;
- }
- for (i = slice << 5; i < (slice + 1) << 5; i++) {
- j = i2c_smbus_read_byte(client);
- if (j < 0)
- goto exit;
- data->data[i] = (u8) j;
- }
- }
- 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,
-};
-
-static int eeprom_attach_adapter(struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, eeprom_detect);
-}
-
-/* This function is called by i2c_probe */
-static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
-{
- struct i2c_client *new_client;
- struct eeprom_data *data;
- int err = 0;
-
- /* There are three ways we can read the EEPROM data:
- (1) I2C block reads (faster, but unsupported by most adapters)
- (2) Consecutive byte reads (100% overhead)
- (3) Regular byte data reads (200% overhead)
- The third method is not implemented by this driver because all
- known adapters support at least the second. */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA
- | I2C_FUNC_SMBUS_BYTE))
- goto exit;
-
- if (!(data = kzalloc(sizeof(struct eeprom_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
-
- new_client = &data->client;
- memset(data->data, 0xff, EEPROM_SIZE);
- i2c_set_clientdata(new_client, data);
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &eeprom_driver;
- new_client->flags = 0;
-
- /* Fill in the remaining client fields */
- strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE);
- data->valid = 0;
- mutex_init(&data->update_lock);
- data->nature = UNKNOWN;
-
- /* Tell the I2C layer a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto exit_kfree;
-
- /* Detect the Vaio nature of EEPROMs.
- We use the "PCG-" or "VGN-" prefix as the signature. */
- if (address == 0x57) {
- char name[4];
-
- name[0] = i2c_smbus_read_byte_data(new_client, 0x80);
- name[1] = i2c_smbus_read_byte(new_client);
- name[2] = i2c_smbus_read_byte(new_client);
- name[3] = i2c_smbus_read_byte(new_client);
-
- if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) {
- dev_info(&new_client->dev, "Vaio EEPROM detected, "
- "enabling privacy protection\n");
- data->nature = VAIO;
- }
- }
-
- /* create the sysfs eeprom file */
- err = sysfs_create_bin_file(&new_client->dev.kobj, &eeprom_attr);
- if (err)
- goto exit_detach;
-
- return 0;
-
-exit_detach:
- i2c_detach_client(new_client);
-exit_kfree:
- kfree(data);
-exit:
- return err;
-}
-
-static int eeprom_detach_client(struct i2c_client *client)
-{
- int err;
-
- sysfs_remove_bin_file(&client->dev.kobj, &eeprom_attr);
-
- err = i2c_detach_client(client);
- if (err)
- return err;
-
- kfree(i2c_get_clientdata(client));
-
- return 0;
-}
-
-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/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c
deleted file mode 100644
index 2a3160153f5..00000000000
--- a/drivers/i2c/chips/isp1301_omap.c
+++ /dev/null
@@ -1,1650 +0,0 @@
-/*
- * isp1301_omap - ISP 1301 USB transceiver, talking to OMAP OTG controller
- *
- * Copyright (C) 2004 Texas Instruments
- * Copyright (C) 2004 David Brownell
- *
- * 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/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-#include <linux/usb.h>
-#include <linux/usb/otg.h>
-#include <linux/i2c.h>
-#include <linux/workqueue.h>
-
-#include <asm/irq.h>
-#include <asm/arch/usb.h>
-
-
-#ifndef DEBUG
-#undef VERBOSE
-#endif
-
-
-#define DRIVER_VERSION "24 August 2004"
-#define DRIVER_NAME (isp1301_driver.driver.name)
-
-MODULE_DESCRIPTION("ISP1301 USB OTG Transceiver Driver");
-MODULE_LICENSE("GPL");
-
-struct isp1301 {
- struct otg_transceiver otg;
- struct i2c_client client;
- void (*i2c_release)(struct device *dev);
-
- int irq;
- int irq_type;
-
- u32 last_otg_ctrl;
- unsigned working:1;
-
- struct timer_list timer;
-
- /* use keventd context to change the state for us */
- struct work_struct work;
-
- unsigned long todo;
-# define WORK_UPDATE_ISP 0 /* update ISP from OTG */
-# define WORK_UPDATE_OTG 1 /* update OTG from ISP */
-# define WORK_HOST_RESUME 4 /* resume host */
-# define WORK_TIMER 6 /* timer fired */
-# define WORK_STOP 7 /* don't resubmit */
-};
-
-
-/* bits in OTG_CTRL_REG */
-
-#define OTG_XCEIV_OUTPUTS \
- (OTG_ASESSVLD|OTG_BSESSEND|OTG_BSESSVLD|OTG_VBUSVLD|OTG_ID)
-#define OTG_XCEIV_INPUTS \
- (OTG_PULLDOWN|OTG_PULLUP|OTG_DRV_VBUS|OTG_PD_VBUS|OTG_PU_VBUS|OTG_PU_ID)
-#define OTG_CTRL_BITS \
- (OTG_A_BUSREQ|OTG_A_SETB_HNPEN|OTG_B_BUSREQ|OTG_B_HNPEN|OTG_BUSDROP)
- /* and OTG_PULLUP is sometimes written */
-
-#define OTG_CTRL_MASK (OTG_DRIVER_SEL| \
- OTG_XCEIV_OUTPUTS|OTG_XCEIV_INPUTS| \
- OTG_CTRL_BITS)
-
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_MACH_OMAP_H2
-
-/* board-specific PM hooks */
-
-#include <asm/gpio.h>
-#include <asm/arch/mux.h>
-#include <asm/mach-types.h>
-
-
-#if defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE)
-
-#include <linux/i2c/tps65010.h>
-
-#else
-
-static inline int tps65010_set_vbus_draw(unsigned mA)
-{
- pr_debug("tps65010: draw %d mA (STUB)\n", mA);
- return 0;
-}
-
-#endif
-
-static void enable_vbus_draw(struct isp1301 *isp, unsigned mA)
-{
- int status = tps65010_set_vbus_draw(mA);
- if (status < 0)
- pr_debug(" VBUS %d mA error %d\n", mA, status);
-}
-
-static void enable_vbus_source(struct isp1301 *isp)
-{
- /* this board won't supply more than 8mA vbus power.
- * some boards can switch a 100ma "unit load" (or more).
- */
-}
-
-
-/* products will deliver OTG messages with LEDs, GUI, etc */
-static inline void notresponding(struct isp1301 *isp)
-{
- printk(KERN_NOTICE "OTG device not responding.\n");
-}
-
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-/* only two addresses possible */
-#define ISP_BASE 0x2c
-static unsigned short normal_i2c[] = {
- ISP_BASE, ISP_BASE + 1,
- I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
-static struct i2c_driver isp1301_driver;
-
-/* smbus apis are used for portability */
-
-static inline u8
-isp1301_get_u8(struct isp1301 *isp, u8 reg)
-{
- return i2c_smbus_read_byte_data(&isp->client, reg + 0);
-}
-
-static inline int
-isp1301_get_u16(struct isp1301 *isp, u8 reg)
-{
- return i2c_smbus_read_word_data(&isp->client, reg);
-}
-
-static inline int
-isp1301_set_bits(struct isp1301 *isp, u8 reg, u8 bits)
-{
- return i2c_smbus_write_byte_data(&isp->client, reg + 0, bits);
-}
-
-static inline int
-isp1301_clear_bits(struct isp1301 *isp, u8 reg, u8 bits)
-{
- return i2c_smbus_write_byte_data(&isp->client, reg + 1, bits);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* identification */
-#define ISP1301_VENDOR_ID 0x00 /* u16 read */
-#define ISP1301_PRODUCT_ID 0x02 /* u16 read */
-#define ISP1301_BCD_DEVICE 0x14 /* u16 read */
-
-#define I2C_VENDOR_ID_PHILIPS 0x04cc
-#define I2C_PRODUCT_ID_PHILIPS_1301 0x1301
-
-/* operational registers */
-#define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */
-# define MC1_SPEED_REG (1 << 0)
-# define MC1_SUSPEND_REG (1 << 1)
-# define MC1_DAT_SE0 (1 << 2)
-# define MC1_TRANSPARENT (1 << 3)
-# define MC1_BDIS_ACON_EN (1 << 4)
-# define MC1_OE_INT_EN (1 << 5)
-# define MC1_UART_EN (1 << 6)
-# define MC1_MASK 0x7f
-#define ISP1301_MODE_CONTROL_2 0x12 /* u8 read, set, +1 clear */
-# define MC2_GLOBAL_PWR_DN (1 << 0)
-# define MC2_SPD_SUSP_CTRL (1 << 1)
-# define MC2_BI_DI (1 << 2)
-# define MC2_TRANSP_BDIR0 (1 << 3)
-# define MC2_TRANSP_BDIR1 (1 << 4)
-# define MC2_AUDIO_EN (1 << 5)
-# define MC2_PSW_EN (1 << 6)
-# define MC2_EN2V7 (1 << 7)
-#define ISP1301_OTG_CONTROL_1 0x06 /* u8 read, set, +1 clear */
-# define OTG1_DP_PULLUP (1 << 0)
-# define OTG1_DM_PULLUP (1 << 1)
-# define OTG1_DP_PULLDOWN (1 << 2)
-# define OTG1_DM_PULLDOWN (1 << 3)
-# define OTG1_ID_PULLDOWN (1 << 4)
-# define OTG1_VBUS_DRV (1 << 5)
-# define OTG1_VBUS_DISCHRG (1 << 6)
-# define OTG1_VBUS_CHRG (1 << 7)
-#define ISP1301_OTG_STATUS 0x10 /* u8 readonly */
-# define OTG_B_SESS_END (1 << 6)
-# define OTG_B_SESS_VLD (1 << 7)
-
-#define ISP1301_INTERRUPT_SOURCE 0x08 /* u8 read */
-#define ISP1301_INTERRUPT_LATCH 0x0A /* u8 read, set, +1 clear */
-
-#define ISP1301_INTERRUPT_FALLING 0x0C /* u8 read, set, +1 clear */
-#define ISP1301_INTERRUPT_RISING 0x0E /* u8 read, set, +1 clear */
-
-/* same bitfields in all interrupt registers */
-# define INTR_VBUS_VLD (1 << 0)
-# define INTR_SESS_VLD (1 << 1)
-# define INTR_DP_HI (1 << 2)
-# define INTR_ID_GND (1 << 3)
-# define INTR_DM_HI (1 << 4)
-# define INTR_ID_FLOAT (1 << 5)
-# define INTR_BDIS_ACON (1 << 6)
-# define INTR_CR_INT (1 << 7)
-
-/*-------------------------------------------------------------------------*/
-
-static const char *state_string(enum usb_otg_state state)
-{
- switch (state) {
- case OTG_STATE_A_IDLE: return "a_idle";
- case OTG_STATE_A_WAIT_VRISE: return "a_wait_vrise";
- case OTG_STATE_A_WAIT_BCON: return "a_wait_bcon";
- case OTG_STATE_A_HOST: return "a_host";
- case OTG_STATE_A_SUSPEND: return "a_suspend";
- case OTG_STATE_A_PERIPHERAL: return "a_peripheral";
- case OTG_STATE_A_WAIT_VFALL: return "a_wait_vfall";
- case OTG_STATE_A_VBUS_ERR: return "a_vbus_err";
- case OTG_STATE_B_IDLE: return "b_idle";
- case OTG_STATE_B_SRP_INIT: return "b_srp_init";
- case OTG_STATE_B_PERIPHERAL: return "b_peripheral";
- case OTG_STATE_B_WAIT_ACON: return "b_wait_acon";
- case OTG_STATE_B_HOST: return "b_host";
- default: return "UNDEFINED";
- }
-}
-
-static inline const char *state_name(struct isp1301 *isp)
-{
- return state_string(isp->otg.state);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* NOTE: some of this ISP1301 setup is specific to H2 boards;
- * not everything is guarded by board-specific checks, or even using
- * omap_usb_config data to deduce MC1_DAT_SE0 and MC2_BI_DI.
- *
- * ALSO: this currently doesn't use ISP1301 low-power modes
- * while OTG is running.
- */
-
-static void power_down(struct isp1301 *isp)
-{
- isp->otg.state = OTG_STATE_UNDEFINED;
-
- // isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN);
- isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG);
-
- isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_ID_PULLDOWN);
- isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0);
-}
-
-static void power_up(struct isp1301 *isp)
-{
- // isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, MC2_GLOBAL_PWR_DN);
- isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_SUSPEND_REG);
-
- /* do this only when cpu is driving transceiver,
- * so host won't see a low speed device...
- */
- isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0);
-}
-
-#define NO_HOST_SUSPEND
-
-static int host_suspend(struct isp1301 *isp)
-{
-#ifdef NO_HOST_SUSPEND
- return 0;
-#else
- struct device *dev;
-
- if (!isp->otg.host)
- return -ENODEV;
-
- /* Currently ASSUMES only the OTG port matters;
- * other ports could be active...
- */
- dev = isp->otg.host->controller;
- return dev->driver->suspend(dev, 3, 0);
-#endif
-}
-
-static int host_resume(struct isp1301 *isp)
-{
-#ifdef NO_HOST_SUSPEND
- return 0;
-#else
- struct device *dev;
-
- if (!isp->otg.host)
- return -ENODEV;
-
- dev = isp->otg.host->controller;
- return dev->driver->resume(dev, 0);
-#endif
-}
-
-static int gadget_suspend(struct isp1301 *isp)
-{
- isp->otg.gadget->b_hnp_enable = 0;
- isp->otg.gadget->a_hnp_support = 0;
- isp->otg.gadget->a_alt_hnp_support = 0;
- return usb_gadget_vbus_disconnect(isp->otg.gadget);
-}
-
-/*-------------------------------------------------------------------------*/
-
-#define TIMER_MINUTES 10
-#define TIMER_JIFFIES (TIMER_MINUTES * 60 * HZ)
-
-/* Almost all our I2C messaging comes from a work queue's task context.
- * NOTE: guaranteeing certain response times might mean we shouldn't
- * share keventd's work queue; a realtime task might be safest.
- */
-void
-isp1301_defer_work(struct isp1301 *isp, int work)
-{
- int status;
-
- if (isp && !test_and_set_bit(work, &isp->todo)) {
- (void) get_device(&isp->client.dev);
- status = schedule_work(&isp->work);
- if (!status && !isp->working)
- dev_vdbg(&isp->client.dev,
- "work item %d may be lost\n", work);
- }
-}
-
-/* called from irq handlers */
-static void a_idle(struct isp1301 *isp, const char *tag)
-{
- if (isp->otg.state == OTG_STATE_A_IDLE)
- return;
-
- isp->otg.default_a = 1;
- if (isp->otg.host) {
- isp->otg.host->is_b_host = 0;
- host_suspend(isp);
- }
- if (isp->otg.gadget) {
- isp->otg.gadget->is_a_peripheral = 1;
- gadget_suspend(isp);
- }
- isp->otg.state = OTG_STATE_A_IDLE;
- isp->last_otg_ctrl = OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
- pr_debug(" --> %s/%s\n", state_name(isp), tag);
-}
-
-/* called from irq handlers */
-static void b_idle(struct isp1301 *isp, const char *tag)
-{
- if (isp->otg.state == OTG_STATE_B_IDLE)
- return;
-
- isp->otg.default_a = 0;
- if (isp->otg.host) {
- isp->otg.host->is_b_host = 1;
- host_suspend(isp);
- }
- if (isp->otg.gadget) {
- isp->otg.gadget->is_a_peripheral = 0;
- gadget_suspend(isp);
- }
- isp->otg.state = OTG_STATE_B_IDLE;
- isp->last_otg_ctrl = OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
- pr_debug(" --> %s/%s\n", state_name(isp), tag);
-}
-
-static void
-dump_regs(struct isp1301 *isp, const char *label)
-{
-#ifdef DEBUG
- u8 ctrl = isp1301_get_u8(isp, ISP1301_OTG_CONTROL_1);
- u8 status = isp1301_get_u8(isp, ISP1301_OTG_STATUS);
- u8 src = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE);
-
- pr_debug("otg: %06x, %s %s, otg/%02x stat/%02x.%02x\n",
- OTG_CTRL_REG, label, state_name(isp),
- ctrl, status, src);
- /* mode control and irq enables don't change much */
-#endif
-}
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_USB_OTG
-
-/*
- * The OMAP OTG controller handles most of the OTG state transitions.
- *
- * We translate isp1301 outputs (mostly voltage comparator status) into
- * OTG inputs; OTG outputs (mostly pullup/pulldown controls) and HNP state
- * flags into isp1301 inputs ... and infer state transitions.
- */
-
-#ifdef VERBOSE
-
-static void check_state(struct isp1301 *isp, const char *tag)
-{
- enum usb_otg_state state = OTG_STATE_UNDEFINED;
- u8 fsm = OTG_TEST_REG & 0x0ff;
- unsigned extra = 0;
-
- switch (fsm) {
-
- /* default-b */
- case 0x0:
- state = OTG_STATE_B_IDLE;
- break;
- case 0x3:
- case 0x7:
- extra = 1;
- case 0x1:
- state = OTG_STATE_B_PERIPHERAL;
- break;
- case 0x11:
- state = OTG_STATE_B_SRP_INIT;
- break;
-
- /* extra dual-role default-b states */
- case 0x12:
- case 0x13:
- case 0x16:
- extra = 1;
- case 0x17:
- state = OTG_STATE_B_WAIT_ACON;
- break;
- case 0x34:
- state = OTG_STATE_B_HOST;
- break;
-
- /* default-a */
- case 0x36:
- state = OTG_STATE_A_IDLE;
- break;
- case 0x3c:
- state = OTG_STATE_A_WAIT_VFALL;
- break;
- case 0x7d:
- state = OTG_STATE_A_VBUS_ERR;
- break;
- case 0x9e:
- case 0x9f:
- extra = 1;
- case 0x89:
- state = OTG_STATE_A_PERIPHERAL;
- break;
- case 0xb7:
- state = OTG_STATE_A_WAIT_VRISE;
- break;
- case 0xb8:
- state = OTG_STATE_A_WAIT_BCON;
- break;
- case 0xb9:
- state = OTG_STATE_A_HOST;
- break;
- case 0xba:
- state = OTG_STATE_A_SUSPEND;
- break;
- default:
- break;
- }
- if (isp->otg.state == state && !extra)
- return;
- pr_debug("otg: %s FSM %s/%02x, %s, %06x\n", tag,
- state_string(state), fsm, state_name(isp), OTG_CTRL_REG);
-}
-
-#else
-
-static inline void check_state(struct isp1301 *isp, const char *tag) { }
-
-#endif
-
-/* outputs from ISP1301_INTERRUPT_SOURCE */
-static void update_otg1(struct isp1301 *isp, u8 int_src)
-{
- u32 otg_ctrl;
-
- otg_ctrl = OTG_CTRL_REG
- & OTG_CTRL_MASK
- & ~OTG_XCEIV_INPUTS
- & ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD);
- if (int_src & INTR_SESS_VLD)
- otg_ctrl |= OTG_ASESSVLD;
- else if (isp->otg.state == OTG_STATE_A_WAIT_VFALL) {
- a_idle(isp, "vfall");
- otg_ctrl &= ~OTG_CTRL_BITS;
- }
- if (int_src & INTR_VBUS_VLD)
- otg_ctrl |= OTG_VBUSVLD;
- if (int_src & INTR_ID_GND) { /* default-A */
- if (isp->otg.state == OTG_STATE_B_IDLE
- || isp->otg.state == OTG_STATE_UNDEFINED) {
- a_idle(isp, "init");
- return;
- }
- } else { /* default-B */
- otg_ctrl |= OTG_ID;
- if (isp->otg.state == OTG_STATE_A_IDLE
- || isp->otg.state == OTG_STATE_UNDEFINED) {
- b_idle(isp, "init");
- return;
- }
- }
- OTG_CTRL_REG = otg_ctrl;
-}
-
-/* outputs from ISP1301_OTG_STATUS */
-static void update_otg2(struct isp1301 *isp, u8 otg_status)
-{
- u32 otg_ctrl;
-
- otg_ctrl = OTG_CTRL_REG
- & OTG_CTRL_MASK
- & ~OTG_XCEIV_INPUTS
- & ~(OTG_BSESSVLD|OTG_BSESSEND);
- if (otg_status & OTG_B_SESS_VLD)
- otg_ctrl |= OTG_BSESSVLD;
- else if (otg_status & OTG_B_SESS_END)
- otg_ctrl |= OTG_BSESSEND;
- OTG_CTRL_REG = otg_ctrl;
-}
-
-/* inputs going to ISP1301 */
-static void otg_update_isp(struct isp1301 *isp)
-{
- u32 otg_ctrl, otg_change;
- u8 set = OTG1_DM_PULLDOWN, clr = OTG1_DM_PULLUP;
-
- otg_ctrl = OTG_CTRL_REG;
- otg_change = otg_ctrl ^ isp->last_otg_ctrl;
- isp->last_otg_ctrl = otg_ctrl;
- otg_ctrl = otg_ctrl & OTG_XCEIV_INPUTS;
-
- switch (isp->otg.state) {
- case OTG_STATE_B_IDLE:
- case OTG_STATE_B_PERIPHERAL:
- case OTG_STATE_B_SRP_INIT:
- if (!(otg_ctrl & OTG_PULLUP)) {
- // if (otg_ctrl & OTG_B_HNPEN) {
- if (isp->otg.gadget->b_hnp_enable) {
- isp->otg.state = OTG_STATE_B_WAIT_ACON;
- pr_debug(" --> b_wait_acon\n");
- }
- goto pulldown;
- }
-pullup:
- set |= OTG1_DP_PULLUP;
- clr |= OTG1_DP_PULLDOWN;
- break;
- case OTG_STATE_A_SUSPEND:
- case OTG_STATE_A_PERIPHERAL:
- if (otg_ctrl & OTG_PULLUP)
- goto pullup;
- /* FALLTHROUGH */
- // case OTG_STATE_B_WAIT_ACON:
- default:
-pulldown:
- set |= OTG1_DP_PULLDOWN;
- clr |= OTG1_DP_PULLUP;
- break;
- }
-
-# define toggle(OTG,ISP) do { \
- if (otg_ctrl & OTG) set |= ISP; \
- else clr |= ISP; \
- } while (0)
-
- if (!(isp->otg.host))
- otg_ctrl &= ~OTG_DRV_VBUS;
-
- switch (isp->otg.state) {
- case OTG_STATE_A_SUSPEND:
- if (otg_ctrl & OTG_DRV_VBUS) {
- set |= OTG1_VBUS_DRV;
- break;
- }
- /* HNP failed for some reason (A_AIDL_BDIS timeout) */
- notresponding(isp);
-
- /* FALLTHROUGH */
- case OTG_STATE_A_VBUS_ERR:
- isp->otg.state = OTG_STATE_A_WAIT_VFALL;
- pr_debug(" --> a_wait_vfall\n");
- /* FALLTHROUGH */
- case OTG_STATE_A_WAIT_VFALL:
- /* FIXME usbcore thinks port power is still on ... */
- clr |= OTG1_VBUS_DRV;
- break;
- case OTG_STATE_A_IDLE:
- if (otg_ctrl & OTG_DRV_VBUS) {
- isp->otg.state = OTG_STATE_A_WAIT_VRISE;
- pr_debug(" --> a_wait_vrise\n");
- }
- /* FALLTHROUGH */
- default:
- toggle(OTG_DRV_VBUS, OTG1_VBUS_DRV);
- }
-
- toggle(OTG_PU_VBUS, OTG1_VBUS_CHRG);
- toggle(OTG_PD_VBUS, OTG1_VBUS_DISCHRG);
-
-# undef toggle
-
- isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, set);
- isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, clr);
-
- /* HNP switch to host or peripheral; and SRP */
- if (otg_change & OTG_PULLUP) {
- switch (isp->otg.state) {
- case OTG_STATE_B_IDLE:
- if (clr & OTG1_DP_PULLUP)
- break;
- isp->otg.state = OTG_STATE_B_PERIPHERAL;
- pr_debug(" --> b_peripheral\n");
- break;
- case OTG_STATE_A_SUSPEND:
- if (clr & OTG1_DP_PULLUP)
- break;
- isp->otg.state = OTG_STATE_A_PERIPHERAL;
- pr_debug(" --> a_peripheral\n");
- break;
- default:
- break;
- }
- OTG_CTRL_REG |= OTG_PULLUP;
- }
-
- check_state(isp, __FUNCTION__);
- dump_regs(isp, "otg->isp1301");
-}
-
-static irqreturn_t omap_otg_irq(int irq, void *_isp)
-{
- u16 otg_irq = OTG_IRQ_SRC_REG;
- u32 otg_ctrl;
- int ret = IRQ_NONE;
- struct isp1301 *isp = _isp;
-
- /* update ISP1301 transciever from OTG controller */
- if (otg_irq & OPRT_CHG) {
- OTG_IRQ_SRC_REG = OPRT_CHG;
- isp1301_defer_work(isp, WORK_UPDATE_ISP);
- ret = IRQ_HANDLED;
-
- /* SRP to become b_peripheral failed */
- } else if (otg_irq & B_SRP_TMROUT) {
- pr_debug("otg: B_SRP_TIMEOUT, %06x\n", OTG_CTRL_REG);
- notresponding(isp);
-
- /* gadget drivers that care should monitor all kinds of
- * remote wakeup (SRP, normal) using their own timer
- * to give "check cable and A-device" messages.
- */
- if (isp->otg.state == OTG_STATE_B_SRP_INIT)
- b_idle(isp, "srp_timeout");
-
- OTG_IRQ_SRC_REG = B_SRP_TMROUT;
- ret = IRQ_HANDLED;
-
- /* HNP to become b_host failed */
- } else if (otg_irq & B_HNP_FAIL) {
- pr_debug("otg: %s B_HNP_FAIL, %06x\n",
- state_name(isp), OTG_CTRL_REG);
- notresponding(isp);
-
- otg_ctrl = OTG_CTRL_REG;
- otg_ctrl |= OTG_BUSDROP;
- otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS;
- OTG_CTRL_REG = otg_ctrl;
-
- /* subset of b_peripheral()... */
- isp->otg.state = OTG_STATE_B_PERIPHERAL;
- pr_debug(" --> b_peripheral\n");
-
- OTG_IRQ_SRC_REG = B_HNP_FAIL;
- ret = IRQ_HANDLED;
-
- /* detect SRP from B-device ... */
- } else if (otg_irq & A_SRP_DETECT) {
- pr_debug("otg: %s SRP_DETECT, %06x\n",
- state_name(isp), OTG_CTRL_REG);
-
- isp1301_defer_work(isp, WORK_UPDATE_OTG);
- switch (isp->otg.state) {
- case OTG_STATE_A_IDLE:
- if (!isp->otg.host)
- break;
- isp1301_defer_work(isp, WORK_HOST_RESUME);
- otg_ctrl = OTG_CTRL_REG;
- otg_ctrl |= OTG_A_BUSREQ;
- otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ)
- & ~OTG_XCEIV_INPUTS
- & OTG_CTRL_MASK;
- OTG_CTRL_REG = otg_ctrl;
- break;
- default:
- break;
- }
-
- OTG_IRQ_SRC_REG = A_SRP_DETECT;
- ret = IRQ_HANDLED;
-
- /* timer expired: T(a_wait_bcon) and maybe T(a_wait_vrise)
- * we don't track them separately
- */
- } else if (otg_irq & A_REQ_TMROUT) {
- otg_ctrl = OTG_CTRL_REG;
- pr_info("otg: BCON_TMOUT from %s, %06x\n",
- state_name(isp), otg_ctrl);
- notresponding(isp);
-
- otg_ctrl |= OTG_BUSDROP;
- otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS;
- OTG_CTRL_REG = otg_ctrl;
- isp->otg.state = OTG_STATE_A_WAIT_VFALL;
-
- OTG_IRQ_SRC_REG = A_REQ_TMROUT;
- ret = IRQ_HANDLED;
-
- /* A-supplied voltage fell too low; overcurrent */
- } else if (otg_irq & A_VBUS_ERR) {
- otg_ctrl = OTG_CTRL_REG;
- printk(KERN_ERR "otg: %s, VBUS_ERR %04x ctrl %06x\n",
- state_name(isp), otg_irq, otg_ctrl);
-
- otg_ctrl |= OTG_BUSDROP;
- otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS;
- OTG_CTRL_REG = otg_ctrl;
- isp->otg.state = OTG_STATE_A_VBUS_ERR;
-
- OTG_IRQ_SRC_REG = A_VBUS_ERR;
- ret = IRQ_HANDLED;
-
- /* switch driver; the transciever code activates it,
- * ungating the udc clock or resuming OHCI.
- */
- } else if (otg_irq & DRIVER_SWITCH) {
- int kick = 0;
-
- otg_ctrl = OTG_CTRL_REG;
- printk(KERN_NOTICE "otg: %s, SWITCH to %s, ctrl %06x\n",
- state_name(isp),
- (otg_ctrl & OTG_DRIVER_SEL)
- ? "gadget" : "host",
- otg_ctrl);
- isp1301_defer_work(isp, WORK_UPDATE_ISP);
-
- /* role is peripheral */
- if (otg_ctrl & OTG_DRIVER_SEL) {
- switch (isp->otg.state) {
- case OTG_STATE_A_IDLE:
- b_idle(isp, __FUNCTION__);
- break;
- default:
- break;
- }
- isp1301_defer_work(isp, WORK_UPDATE_ISP);
-
- /* role is host */
- } else {
- if (!(otg_ctrl & OTG_ID)) {
- otg_ctrl &= OTG_CTRL_MASK & ~OTG_XCEIV_INPUTS;
- OTG_CTRL_REG = otg_ctrl | OTG_A_BUSREQ;
- }
-
- if (isp->otg.host) {
- switch (isp->otg.state) {
- case OTG_STATE_B_WAIT_ACON:
- isp->otg.state = OTG_STATE_B_HOST;
- pr_debug(" --> b_host\n");
- kick = 1;
- break;
- case OTG_STATE_A_WAIT_BCON:
- isp->otg.state = OTG_STATE_A_HOST;
- pr_debug(" --> a_host\n");
- break;
- case OTG_STATE_A_PERIPHERAL:
- isp->otg.state = OTG_STATE_A_WAIT_BCON;
- pr_debug(" --> a_wait_bcon\n");
- break;
- default:
- break;
- }
- isp1301_defer_work(isp, WORK_HOST_RESUME);
- }
- }
-
- OTG_IRQ_SRC_REG = DRIVER_SWITCH;
- ret = IRQ_HANDLED;
-
- if (kick)
- usb_bus_start_enum(isp->otg.host,
- isp->otg.host->otg_port);
- }
-
- check_state(isp, __FUNCTION__);
- return ret;
-}
-
-static struct platform_device *otg_dev;
-
-static int otg_init(struct isp1301 *isp)
-{
- if (!otg_dev)
- return -ENODEV;
-
- dump_regs(isp, __FUNCTION__);
- /* some of these values are board-specific... */
- OTG_SYSCON_2_REG |= OTG_EN
- /* for B-device: */
- | SRP_GPDATA /* 9msec Bdev D+ pulse */
- | SRP_GPDVBUS /* discharge after VBUS pulse */
- // | (3 << 24) /* 2msec VBUS pulse */
- /* for A-device: */
- | (0 << 20) /* 200ms nominal A_WAIT_VRISE timer */
- | SRP_DPW /* detect 167+ns SRP pulses */
- | SRP_DATA | SRP_VBUS /* accept both kinds of SRP pulse */
- ;
-
- update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE));
- update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
-
- check_state(isp, __FUNCTION__);
- pr_debug("otg: %s, %s %06x\n",
- state_name(isp), __FUNCTION__, OTG_CTRL_REG);
-
- OTG_IRQ_EN_REG = DRIVER_SWITCH | OPRT_CHG
- | B_SRP_TMROUT | B_HNP_FAIL
- | A_VBUS_ERR | A_SRP_DETECT | A_REQ_TMROUT;
- OTG_SYSCON_2_REG |= OTG_EN;
-
- return 0;
-}
-
-static int otg_probe(struct platform_device *dev)
-{
- // struct omap_usb_config *config = dev->platform_data;
-
- otg_dev = dev;
- return 0;
-}
-
-static int otg_remove(struct platform_device *dev)
-{
- otg_dev = 0;
- return 0;
-}
-
-struct platform_driver omap_otg_driver = {
- .probe = otg_probe,
- .remove = otg_remove,
- .driver = {
- .owner = THIS_MODULE,
- .name = "omap_otg",
- },
-};
-
-static int otg_bind(struct isp1301 *isp)
-{
- int status;
-
- if (otg_dev)
- return -EBUSY;
-
- status = platform_driver_register(&omap_otg_driver);
- if (status < 0)
- return status;
-
- if (otg_dev)
- status = request_irq(otg_dev->resource[1].start, omap_otg_irq,
- IRQF_DISABLED, DRIVER_NAME, isp);
- else
- status = -ENODEV;
-
- if (status < 0)
- platform_driver_unregister(&omap_otg_driver);
- return status;
-}
-
-static void otg_unbind(struct isp1301 *isp)
-{
- if (!otg_dev)
- return;
- free_irq(otg_dev->resource[1].start, isp);
-}
-
-#else
-
-/* OTG controller isn't clocked */
-
-#endif /* CONFIG_USB_OTG */
-
-/*-------------------------------------------------------------------------*/
-
-static void b_peripheral(struct isp1301 *isp)
-{
- OTG_CTRL_REG = OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
- usb_gadget_vbus_connect(isp->otg.gadget);
-
-#ifdef CONFIG_USB_OTG
- enable_vbus_draw(isp, 8);
- otg_update_isp(isp);
-#else
- enable_vbus_draw(isp, 100);
- /* UDC driver just set OTG_BSESSVLD */
- isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLUP);
- isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_DP_PULLDOWN);
- isp->otg.state = OTG_STATE_B_PERIPHERAL;
- pr_debug(" --> b_peripheral\n");
- dump_regs(isp, "2periph");
-#endif
-}
-
-static void isp_update_otg(struct isp1301 *isp, u8 stat)
-{
- u8 isp_stat, isp_bstat;
- enum usb_otg_state state = isp->otg.state;
-
- if (stat & INTR_BDIS_ACON)
- pr_debug("OTG: BDIS_ACON, %s\n", state_name(isp));
-
- /* start certain state transitions right away */
- isp_stat = isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE);
- if (isp_stat & INTR_ID_GND) {
- if (isp->otg.default_a) {
- switch (state) {
- case OTG_STATE_B_IDLE:
- a_idle(isp, "idle");
- /* FALLTHROUGH */
- case OTG_STATE_A_IDLE:
- enable_vbus_source(isp);
- /* FALLTHROUGH */
- case OTG_STATE_A_WAIT_VRISE:
- /* we skip over OTG_STATE_A_WAIT_BCON, since
- * the HC will transition to A_HOST (or
- * A_SUSPEND!) without our noticing except
- * when HNP is used.
- */
- if (isp_stat & INTR_VBUS_VLD)
- isp->otg.state = OTG_STATE_A_HOST;
- break;
- case OTG_STATE_A_WAIT_VFALL:
- if (!(isp_stat & INTR_SESS_VLD))
- a_idle(isp, "vfell");
- break;
- default:
- if (!(isp_stat & INTR_VBUS_VLD))
- isp->otg.state = OTG_STATE_A_VBUS_ERR;
- break;
- }
- isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS);
- } else {
- switch (state) {
- case OTG_STATE_B_PERIPHERAL:
- case OTG_STATE_B_HOST:
- case OTG_STATE_B_WAIT_ACON:
- usb_gadget_vbus_disconnect(isp->otg.gadget);
- break;
- default:
- break;
- }
- if (state != OTG_STATE_A_IDLE)
- a_idle(isp, "id");
- if (isp->otg.host && state == OTG_STATE_A_IDLE)
- isp1301_defer_work(isp, WORK_HOST_RESUME);
- isp_bstat = 0;
- }
- } else {
- /* if user unplugged mini-A end of cable,
- * don't bypass A_WAIT_VFALL.
- */
- if (isp->otg.default_a) {
- switch (state) {
- default:
- isp->otg.state = OTG_STATE_A_WAIT_VFALL;
- break;
- case OTG_STATE_A_WAIT_VFALL:
- state = OTG_STATE_A_IDLE;
- /* khubd may take a while to notice and
- * handle this disconnect, so don't go
- * to B_IDLE quite yet.
- */
- break;
- case OTG_STATE_A_IDLE:
- host_suspend(isp);
- isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1,
- MC1_BDIS_ACON_EN);
- isp->otg.state = OTG_STATE_B_IDLE;
- OTG_CTRL_REG &= OTG_CTRL_REG & OTG_CTRL_MASK
- & ~OTG_CTRL_BITS;
- break;
- case OTG_STATE_B_IDLE:
- break;
- }
- }
- isp_bstat = isp1301_get_u8(isp, ISP1301_OTG_STATUS);
-
- switch (isp->otg.state) {
- case OTG_STATE_B_PERIPHERAL:
- case OTG_STATE_B_WAIT_ACON:
- case OTG_STATE_B_HOST:
- if (likely(isp_bstat & OTG_B_SESS_VLD))
- break;
- enable_vbus_draw(isp, 0);
-#ifndef CONFIG_USB_OTG
- /* UDC driver will clear OTG_BSESSVLD */
- isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1,
- OTG1_DP_PULLDOWN);
- isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1,
- OTG1_DP_PULLUP);
- dump_regs(isp, __FUNCTION__);
-#endif
- /* FALLTHROUGH */
- case OTG_STATE_B_SRP_INIT:
- b_idle(isp, __FUNCTION__);
- OTG_CTRL_REG &= OTG_CTRL_REG & OTG_XCEIV_OUTPUTS;
- /* FALLTHROUGH */
- case OTG_STATE_B_IDLE:
- if (isp->otg.gadget && (isp_bstat & OTG_B_SESS_VLD)) {
-#ifdef CONFIG_USB_OTG
- update_otg1(isp, isp_stat);
- update_otg2(isp, isp_bstat);
-#endif
- b_peripheral(isp);
- } else if (!(isp_stat & (INTR_VBUS_VLD|INTR_SESS_VLD)))
- isp_bstat |= OTG_B_SESS_END;
- break;
- case OTG_STATE_A_WAIT_VFALL:
- break;
- default:
- pr_debug("otg: unsupported b-device %s\n",
- state_name(isp));
- break;
- }
- }
-
- if (state != isp->otg.state)
- pr_debug(" isp, %s -> %s\n",
- state_string(state), state_name(isp));
-
-#ifdef CONFIG_USB_OTG
- /* update the OTG controller state to match the isp1301; may
- * trigger OPRT_CHG irqs for changes going to the isp1301.
- */
- update_otg1(isp, isp_stat);
- update_otg2(isp, isp_bstat);
- check_state(isp, __FUNCTION__);
-#endif
-
- dump_regs(isp, "isp1301->otg");
-}
-
-/*-------------------------------------------------------------------------*/
-
-static u8 isp1301_clear_latch(struct isp1301 *isp)
-{
- u8 latch = isp1301_get_u8(isp, ISP1301_INTERRUPT_LATCH);
- isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, latch);
- return latch;
-}
-
-static void
-isp1301_work(struct work_struct *work)
-{
- struct isp1301 *isp = container_of(work, struct isp1301, work);
- int stop;
-
- /* implicit lock: we're the only task using this device */
- isp->working = 1;
- do {
- stop = test_bit(WORK_STOP, &isp->todo);
-
-#ifdef CONFIG_USB_OTG
- /* transfer state from otg engine to isp1301 */
- if (test_and_clear_bit(WORK_UPDATE_ISP, &isp->todo)) {
- otg_update_isp(isp);
- put_device(&isp->client.dev);
- }
-#endif
- /* transfer state from isp1301 to otg engine */
- if (test_and_clear_bit(WORK_UPDATE_OTG, &isp->todo)) {
- u8 stat = isp1301_clear_latch(isp);
-
- isp_update_otg(isp, stat);
- put_device(&isp->client.dev);
- }
-
- if (test_and_clear_bit(WORK_HOST_RESUME, &isp->todo)) {
- u32 otg_ctrl;
-
- /*
- * skip A_WAIT_VRISE; hc transitions invisibly
- * skip A_WAIT_BCON; same.
- */
- switch (isp->otg.state) {
- case OTG_STATE_A_WAIT_BCON:
- case OTG_STATE_A_WAIT_VRISE:
- isp->otg.state = OTG_STATE_A_HOST;
- pr_debug(" --> a_host\n");
- otg_ctrl = OTG_CTRL_REG;
- otg_ctrl |= OTG_A_BUSREQ;
- otg_ctrl &= ~(OTG_BUSDROP|OTG_B_BUSREQ)
- & OTG_CTRL_MASK;
- OTG_CTRL_REG = otg_ctrl;
- break;
- case OTG_STATE_B_WAIT_ACON:
- isp->otg.state = OTG_STATE_B_HOST;
- pr_debug(" --> b_host (acon)\n");
- break;
- case OTG_STATE_B_HOST:
- case OTG_STATE_B_IDLE:
- case OTG_STATE_A_IDLE:
- break;
- default:
- pr_debug(" host resume in %s\n",
- state_name(isp));
- }
- host_resume(isp);
- // mdelay(10);
- put_device(&isp->client.dev);
- }
-
- if (test_and_clear_bit(WORK_TIMER, &isp->todo)) {
-#ifdef VERBOSE
- dump_regs(isp, "timer");
- if (!stop)
- mod_timer(&isp->timer, jiffies + TIMER_JIFFIES);
-#endif
- put_device(&isp->client.dev);
- }
-
- if (isp->todo)
- dev_vdbg(&isp->client.dev,
- "work done, todo = 0x%lx\n",
- isp->todo);
- if (stop) {
- dev_dbg(&isp->client.dev, "stop\n");
- break;
- }
- } while (isp->todo);
- isp->working = 0;
-}
-
-static irqreturn_t isp1301_irq(int irq, void *isp)
-{
- isp1301_defer_work(isp, WORK_UPDATE_OTG);
- return IRQ_HANDLED;
-}
-
-static void isp1301_timer(unsigned long _isp)
-{
- isp1301_defer_work((void *)_isp, WORK_TIMER);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void isp1301_release(struct device *dev)
-{
- struct isp1301 *isp;
-
- isp = container_of(dev, struct isp1301, client.dev);
-
- /* ugly -- i2c hijacks our memory hook to wait_for_completion() */
- if (isp->i2c_release)
- isp->i2c_release(dev);
- kfree (isp);
-}
-
-static struct isp1301 *the_transceiver;
-
-static int isp1301_detach_client(struct i2c_client *i2c)
-{
- struct isp1301 *isp;
-
- isp = container_of(i2c, struct isp1301, client);
-
- isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0);
- isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0);
- free_irq(isp->irq, isp);
-#ifdef CONFIG_USB_OTG
- otg_unbind(isp);
-#endif
- if (machine_is_omap_h2())
- omap_free_gpio(2);
-
- isp->timer.data = 0;
- set_bit(WORK_STOP, &isp->todo);
- del_timer_sync(&isp->timer);
- flush_scheduled_work();
-
- put_device(&i2c->dev);
- the_transceiver = 0;
-
- return i2c_detach_client(i2c);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* NOTE: three modes are possible here, only one of which
- * will be standards-conformant on any given system:
- *
- * - OTG mode (dual-role), required if there's a Mini-AB connector
- * - HOST mode, for when there's one or more A (host) connectors
- * - DEVICE mode, for when there's a B/Mini-B (device) connector
- *
- * As a rule, you won't have an isp1301 chip unless it's there to
- * support the OTG mode. Other modes help testing USB controllers
- * in isolation from (full) OTG support, or maybe so later board
- * revisions can help to support those feature.
- */
-
-#ifdef CONFIG_USB_OTG
-
-static int isp1301_otg_enable(struct isp1301 *isp)
-{
- power_up(isp);
- otg_init(isp);
-
- /* NOTE: since we don't change this, this provides
- * a few more interrupts than are strictly needed.
- */
- isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING,
- INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND);
- isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
- INTR_VBUS_VLD | INTR_SESS_VLD | INTR_ID_GND);
-
- dev_info(&isp->client.dev, "ready for dual-role USB ...\n");
-
- return 0;
-}
-
-#endif
-
-/* add or disable the host device+driver */
-static int
-isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host)
-{
- struct isp1301 *isp = container_of(otg, struct isp1301, otg);
-
- if (!otg || isp != the_transceiver)
- return -ENODEV;
-
- if (!host) {
- OTG_IRQ_EN_REG = 0;
- power_down(isp);
- isp->otg.host = 0;
- return 0;
- }
-
-#ifdef CONFIG_USB_OTG
- isp->otg.host = host;
- dev_dbg(&isp->client.dev, "registered host\n");
- host_suspend(isp);
- if (isp->otg.gadget)
- return isp1301_otg_enable(isp);
- return 0;
-
-#elif !defined(CONFIG_USB_GADGET_OMAP)
- // FIXME update its refcount
- isp->otg.host = host;
-
- power_up(isp);
-
- if (machine_is_omap_h2())
- isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0);
-
- dev_info(&isp->client.dev, "A-Host sessions ok\n");
- isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING,
- INTR_ID_GND);
- isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
- INTR_ID_GND);
-
- /* If this has a Mini-AB connector, this mode is highly
- * nonstandard ... but can be handy for testing, especially with
- * the Mini-A end of an OTG cable. (Or something nonstandard
- * like MiniB-to-StandardB, maybe built with a gender mender.)
- */
- isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1, OTG1_VBUS_DRV);
-
- dump_regs(isp, __FUNCTION__);
-
- return 0;
-
-#else
- dev_dbg(&isp->client.dev, "host sessions not allowed\n");
- return -EINVAL;
-#endif
-
-}
-
-static int
-isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
-{
- struct isp1301 *isp = container_of(otg, struct isp1301, otg);
-
- if (!otg || isp != the_transceiver)
- return -ENODEV;
-
- if (!gadget) {
- OTG_IRQ_EN_REG = 0;
- if (!isp->otg.default_a)
- enable_vbus_draw(isp, 0);
- usb_gadget_vbus_disconnect(isp->otg.gadget);
- isp->otg.gadget = 0;
- power_down(isp);
- return 0;
- }
-
-#ifdef CONFIG_USB_OTG
- isp->otg.gadget = gadget;
- dev_dbg(&isp->client.dev, "registered gadget\n");
- /* gadget driver may be suspended until vbus_connect () */
- if (isp->otg.host)
- return isp1301_otg_enable(isp);
- return 0;
-
-#elif !defined(CONFIG_USB_OHCI_HCD) && !defined(CONFIG_USB_OHCI_HCD_MODULE)
- isp->otg.gadget = gadget;
- // FIXME update its refcount
-
- OTG_CTRL_REG = (OTG_CTRL_REG & OTG_CTRL_MASK
- & ~(OTG_XCEIV_OUTPUTS|OTG_CTRL_BITS))
- | OTG_ID;
- power_up(isp);
- isp->otg.state = OTG_STATE_B_IDLE;
-
- if (machine_is_omap_h2())
- isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0);
-
- isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING,
- INTR_SESS_VLD);
- isp1301_set_bits(isp, ISP1301_INTERRUPT_FALLING,
- INTR_VBUS_VLD);
- dev_info(&isp->client.dev, "B-Peripheral sessions ok\n");
- dump_regs(isp, __FUNCTION__);
-
- /* If this has a Mini-AB connector, this mode is highly
- * nonstandard ... but can be handy for testing, so long
- * as you don't plug a Mini-A cable into the jack.
- */
- if (isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE) & INTR_VBUS_VLD)
- b_peripheral(isp);
-
- return 0;
-
-#else
- dev_dbg(&isp->client.dev, "peripheral sessions not allowed\n");
- return -EINVAL;
-#endif
-}
-
-
-/*-------------------------------------------------------------------------*/
-
-static int
-isp1301_set_power(struct otg_transceiver *dev, unsigned mA)
-{
- if (!the_transceiver)
- return -ENODEV;
- if (dev->state == OTG_STATE_B_PERIPHERAL)
- enable_vbus_draw(the_transceiver, mA);
- return 0;
-}
-
-static int
-isp1301_start_srp(struct otg_transceiver *dev)
-{
- struct isp1301 *isp = container_of(dev, struct isp1301, otg);
- u32 otg_ctrl;
-
- if (!dev || isp != the_transceiver
- || isp->otg.state != OTG_STATE_B_IDLE)
- return -ENODEV;
-
- otg_ctrl = OTG_CTRL_REG;
- if (!(otg_ctrl & OTG_BSESSEND))
- return -EINVAL;
-
- otg_ctrl |= OTG_B_BUSREQ;
- otg_ctrl &= ~OTG_A_BUSREQ & OTG_CTRL_MASK;
- OTG_CTRL_REG = otg_ctrl;
- isp->otg.state = OTG_STATE_B_SRP_INIT;
-
- pr_debug("otg: SRP, %s ... %06x\n", state_name(isp), OTG_CTRL_REG);
-#ifdef CONFIG_USB_OTG
- check_state(isp, __FUNCTION__);
-#endif
- return 0;
-}
-
-static int
-isp1301_start_hnp(struct otg_transceiver *dev)
-{
-#ifdef CONFIG_USB_OTG
- struct isp1301 *isp = container_of(dev, struct isp1301, otg);
-
- if (!dev || isp != the_transceiver)
- return -ENODEV;
- if (isp->otg.default_a && (isp->otg.host == NULL
- || !isp->otg.host->b_hnp_enable))
- return -ENOTCONN;
- if (!isp->otg.default_a && (isp->otg.gadget == NULL
- || !isp->otg.gadget->b_hnp_enable))
- return -ENOTCONN;
-
- /* We want hardware to manage most HNP protocol timings.
- * So do this part as early as possible...
- */
- switch (isp->otg.state) {
- case OTG_STATE_B_HOST:
- isp->otg.state = OTG_STATE_B_PERIPHERAL;
- /* caller will suspend next */
- break;
- case OTG_STATE_A_HOST:
-#if 0
- /* autoconnect mode avoids irq latency bugs */
- isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1,
- MC1_BDIS_ACON_EN);
-#endif
- /* caller must suspend then clear A_BUSREQ */
- usb_gadget_vbus_connect(isp->otg.gadget);
- OTG_CTRL_REG |= OTG_A_SETB_HNPEN;
-
- break;
- case OTG_STATE_A_PERIPHERAL:
- /* initiated by B-Host suspend */
- break;
- default:
- return -EILSEQ;
- }
- pr_debug("otg: HNP %s, %06x ...\n",
- state_name(isp), OTG_CTRL_REG);
- check_state(isp, __FUNCTION__);
- return 0;
-#else
- /* srp-only */
- return -EINVAL;
-#endif
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* no error returns, they'd just make bus scanning stop */
-static int isp1301_probe(struct i2c_adapter *bus, int address, int kind)
-{
- int status;
- struct isp1301 *isp;
- struct i2c_client *i2c;
-
- if (the_transceiver)
- return 0;
-
- isp = kzalloc(sizeof *isp, GFP_KERNEL);
- if (!isp)
- return 0;
-
- INIT_WORK(&isp->work, isp1301_work);
- init_timer(&isp->timer);
- isp->timer.function = isp1301_timer;
- isp->timer.data = (unsigned long) isp;
-
- isp->irq = -1;
- isp->client.addr = address;
- i2c_set_clientdata(&isp->client, isp);
- isp->client.adapter = bus;
- isp->client.driver = &isp1301_driver;
- strlcpy(isp->client.name, DRIVER_NAME, I2C_NAME_SIZE);
- i2c = &isp->client;
-
- /* if this is a true probe, verify the chip ... */
- if (kind < 0) {
- status = isp1301_get_u16(isp, ISP1301_VENDOR_ID);
- if (status != I2C_VENDOR_ID_PHILIPS) {
- dev_dbg(&bus->dev, "addr %d not philips id: %d\n",
- address, status);
- goto fail1;
- }
- status = isp1301_get_u16(isp, ISP1301_PRODUCT_ID);
- if (status != I2C_PRODUCT_ID_PHILIPS_1301) {
- dev_dbg(&bus->dev, "%d not isp1301, %d\n",
- address, status);
- goto fail1;
- }
- }
-
- status = i2c_attach_client(i2c);
- if (status < 0) {
- dev_dbg(&bus->dev, "can't attach %s to device %d, err %d\n",
- DRIVER_NAME, address, status);
-fail1:
- kfree(isp);
- return 0;
- }
- isp->i2c_release = i2c->dev.release;
- i2c->dev.release = isp1301_release;
-
- /* initial development used chiprev 2.00 */
- status = i2c_smbus_read_word_data(i2c, ISP1301_BCD_DEVICE);
- dev_info(&i2c->dev, "chiprev %x.%02x, driver " DRIVER_VERSION "\n",
- status >> 8, status & 0xff);
-
- /* make like power-on reset */
- isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_1, MC1_MASK);
-
- isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2, MC2_BI_DI);
- isp1301_clear_bits(isp, ISP1301_MODE_CONTROL_2, ~MC2_BI_DI);
-
- isp1301_set_bits(isp, ISP1301_OTG_CONTROL_1,
- OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN);
- isp1301_clear_bits(isp, ISP1301_OTG_CONTROL_1,
- ~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN));
-
- isp1301_clear_bits(isp, ISP1301_INTERRUPT_LATCH, ~0);
- isp1301_clear_bits(isp, ISP1301_INTERRUPT_FALLING, ~0);
- isp1301_clear_bits(isp, ISP1301_INTERRUPT_RISING, ~0);
-
-#ifdef CONFIG_USB_OTG
- status = otg_bind(isp);
- if (status < 0) {
- dev_dbg(&i2c->dev, "can't bind OTG\n");
- goto fail2;
- }
-#endif
-
- if (machine_is_omap_h2()) {
- /* full speed signaling by default */
- isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1,
- MC1_SPEED_REG);
- isp1301_set_bits(isp, ISP1301_MODE_CONTROL_2,
- MC2_SPD_SUSP_CTRL);
-
- /* IRQ wired at M14 */
- omap_cfg_reg(M14_1510_GPIO2);
- isp->irq = OMAP_GPIO_IRQ(2);
- if (gpio_request(2, "isp1301") == 0)
- gpio_direction_input(2);
- isp->irq_type = IRQF_TRIGGER_FALLING;
- }
-
- isp->irq_type |= IRQF_SAMPLE_RANDOM;
- status = request_irq(isp->irq, isp1301_irq,
- isp->irq_type, DRIVER_NAME, isp);
- if (status < 0) {
- dev_dbg(&i2c->dev, "can't get IRQ %d, err %d\n",
- isp->irq, status);
-#ifdef CONFIG_USB_OTG
-fail2:
-#endif
- i2c_detach_client(i2c);
- goto fail1;
- }
-
- isp->otg.dev = &isp->client.dev;
- isp->otg.label = DRIVER_NAME;
-
- isp->otg.set_host = isp1301_set_host,
- isp->otg.set_peripheral = isp1301_set_peripheral,
- isp->otg.set_power = isp1301_set_power,
- isp->otg.start_srp = isp1301_start_srp,
- isp->otg.start_hnp = isp1301_start_hnp,
-
- enable_vbus_draw(isp, 0);
- power_down(isp);
- the_transceiver = isp;
-
-#ifdef CONFIG_USB_OTG
- update_otg1(isp, isp1301_get_u8(isp, ISP1301_INTERRUPT_SOURCE));
- update_otg2(isp, isp1301_get_u8(isp, ISP1301_OTG_STATUS));
-#endif
-
- dump_regs(isp, __FUNCTION__);
-
-#ifdef VERBOSE
- mod_timer(&isp->timer, jiffies + TIMER_JIFFIES);
- dev_dbg(&i2c->dev, "scheduled timer, %d min\n", TIMER_MINUTES);
-#endif
-
- status = otg_set_transceiver(&isp->otg);
- if (status < 0)
- dev_err(&i2c->dev, "can't register transceiver, %d\n",
- status);
-
- return 0;
-}
-
-static int isp1301_scan_bus(struct i2c_adapter *bus)
-{
- if (!i2c_check_functionality(bus, I2C_FUNC_SMBUS_BYTE_DATA
- | I2C_FUNC_SMBUS_READ_WORD_DATA))
- return -EINVAL;
- return i2c_probe(bus, &addr_data, isp1301_probe);
-}
-
-static struct i2c_driver isp1301_driver = {
- .driver = {
- .name = "isp1301_omap",
- },
- .attach_adapter = isp1301_scan_bus,
- .detach_client = isp1301_detach_client,
-};
-
-/*-------------------------------------------------------------------------*/
-
-static int __init isp_init(void)
-{
- return i2c_add_driver(&isp1301_driver);
-}
-module_init(isp_init);
-
-static void __exit isp_exit(void)
-{
- if (the_transceiver)
- otg_set_transceiver(0);
- i2c_del_driver(&isp1301_driver);
-}
-module_exit(isp_exit);
-
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c
deleted file mode 100644
index fb7ea5637ec..00000000000
--- a/drivers/i2c/chips/max6875.c
+++ /dev/null
@@ -1,273 +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 client;
- struct mutex update_lock;
-
- u32 valid;
- u8 data[USER_EEPROM_SIZE];
- unsigned long last_updated[USER_EEPROM_SLICES];
-};
-
-static int max6875_attach_adapter(struct i2c_adapter *adapter);
-static int max6875_detect(struct i2c_adapter *adapter, int address, int kind);
-static int max6875_detach_client(struct i2c_client *client);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver max6875_driver = {
- .driver = {
- .name = "max6875",
- },
- .attach_adapter = max6875_attach_adapter,
- .detach_client = max6875_detach_client,
-};
-
-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,
-};
-
-static int max6875_attach_adapter(struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, max6875_detect);
-}
-
-/* This function is called by i2c_probe */
-static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
-{
- struct i2c_client *real_client;
- struct i2c_client *fake_client;
- struct max6875_data *data;
- int err = 0;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA
- | I2C_FUNC_SMBUS_READ_BYTE))
- return 0;
-
- /* Only check even addresses */
- if (address & 1)
- return 0;
-
- if (!(data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL)))
- return -ENOMEM;
-
- /* A fake client is created on the odd address */
- if (!(fake_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit_kfree1;
- }
-
- /* Init real i2c_client */
- real_client = &data->client;
- i2c_set_clientdata(real_client, data);
- real_client->addr = address;
- real_client->adapter = adapter;
- real_client->driver = &max6875_driver;
- real_client->flags = 0;
- strlcpy(real_client->name, "max6875", I2C_NAME_SIZE);
- mutex_init(&data->update_lock);
-
- /* Init fake client data */
- i2c_set_clientdata(fake_client, NULL);
- fake_client->addr = address | 1;
- fake_client->adapter = adapter;
- fake_client->driver = &max6875_driver;
- fake_client->flags = 0;
- strlcpy(fake_client->name, "max6875 subclient", I2C_NAME_SIZE);
-
- /* Prevent 24RF08 corruption (in case of user error) */
- i2c_smbus_write_quick(real_client, 0);
-
- if ((err = i2c_attach_client(real_client)) != 0)
- goto exit_kfree2;
-
- if ((err = i2c_attach_client(fake_client)) != 0)
- goto exit_detach1;
-
- err = sysfs_create_bin_file(&real_client->dev.kobj, &user_eeprom_attr);
- if (err)
- goto exit_detach2;
-
- return 0;
-
-exit_detach2:
- i2c_detach_client(fake_client);
-exit_detach1:
- i2c_detach_client(real_client);
-exit_kfree2:
- kfree(fake_client);
-exit_kfree1:
- kfree(data);
- return err;
-}
-
-/* Will be called for both the real client and the fake client */
-static int max6875_detach_client(struct i2c_client *client)
-{
- int err;
- struct max6875_data *data = i2c_get_clientdata(client);
-
- /* data is NULL for the fake client */
- if (data)
- sysfs_remove_bin_file(&client->dev.kobj, &user_eeprom_attr);
-
- err = i2c_detach_client(client);
- if (err)
- return err;
-
- if (data) /* real client */
- kfree(data);
- else /* fake client */
- kfree(client);
- return 0;
-}
-
-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/menelaus.c b/drivers/i2c/chips/menelaus.c
deleted file mode 100644
index 2dea0123a95..00000000000
--- a/drivers/i2c/chips/menelaus.c
+++ /dev/null
@@ -1,1278 +0,0 @@
-/*
- * Copyright (C) 2004 Texas Instruments, Inc.
- *
- * Some parts based tps65010.c:
- * Copyright (C) 2004 Texas Instruments and
- * Copyright (C) 2004-2005 David Brownell
- *
- * Some parts based on tlv320aic24.c:
- * Copyright (C) by Kai Svahn <kai.svahn@nokia.com>
- *
- * Changes for interrupt handling and clean-up by
- * Tony Lindgren <tony@atomide.com> and Imre Deak <imre.deak@nokia.com>
- * Cleanup and generalized support for voltage setting by
- * Juha Yrjola
- * Added support for controlling VCORE and regulator sleep states,
- * Amit Kucheria <amit.kucheria@nokia.com>
- * Copyright (C) 2005, 2006 Nokia Corporation
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-#include <linux/mutex.h>
-#include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/irq.h>
-
-#include <asm/arch/gpio.h>
-#include <asm/arch/menelaus.h>
-
-#define DRIVER_NAME "menelaus"
-
-#define MENELAUS_I2C_ADDRESS 0x72
-
-#define MENELAUS_REV 0x01
-#define MENELAUS_VCORE_CTRL1 0x02
-#define MENELAUS_VCORE_CTRL2 0x03
-#define MENELAUS_VCORE_CTRL3 0x04
-#define MENELAUS_VCORE_CTRL4 0x05
-#define MENELAUS_VCORE_CTRL5 0x06
-#define MENELAUS_DCDC_CTRL1 0x07
-#define MENELAUS_DCDC_CTRL2 0x08
-#define MENELAUS_DCDC_CTRL3 0x09
-#define MENELAUS_LDO_CTRL1 0x0A
-#define MENELAUS_LDO_CTRL2 0x0B
-#define MENELAUS_LDO_CTRL3 0x0C
-#define MENELAUS_LDO_CTRL4 0x0D
-#define MENELAUS_LDO_CTRL5 0x0E
-#define MENELAUS_LDO_CTRL6 0x0F
-#define MENELAUS_LDO_CTRL7 0x10
-#define MENELAUS_LDO_CTRL8 0x11
-#define MENELAUS_SLEEP_CTRL1 0x12
-#define MENELAUS_SLEEP_CTRL2 0x13
-#define MENELAUS_DEVICE_OFF 0x14
-#define MENELAUS_OSC_CTRL 0x15
-#define MENELAUS_DETECT_CTRL 0x16
-#define MENELAUS_INT_MASK1 0x17
-#define MENELAUS_INT_MASK2 0x18
-#define MENELAUS_INT_STATUS1 0x19
-#define MENELAUS_INT_STATUS2 0x1A
-#define MENELAUS_INT_ACK1 0x1B
-#define MENELAUS_INT_ACK2 0x1C
-#define MENELAUS_GPIO_CTRL 0x1D
-#define MENELAUS_GPIO_IN 0x1E
-#define MENELAUS_GPIO_OUT 0x1F
-#define MENELAUS_BBSMS 0x20
-#define MENELAUS_RTC_CTRL 0x21
-#define MENELAUS_RTC_UPDATE 0x22
-#define MENELAUS_RTC_SEC 0x23
-#define MENELAUS_RTC_MIN 0x24
-#define MENELAUS_RTC_HR 0x25
-#define MENELAUS_RTC_DAY 0x26
-#define MENELAUS_RTC_MON 0x27
-#define MENELAUS_RTC_YR 0x28
-#define MENELAUS_RTC_WKDAY 0x29
-#define MENELAUS_RTC_AL_SEC 0x2A
-#define MENELAUS_RTC_AL_MIN 0x2B
-#define MENELAUS_RTC_AL_HR 0x2C
-#define MENELAUS_RTC_AL_DAY 0x2D
-#define MENELAUS_RTC_AL_MON 0x2E
-#define MENELAUS_RTC_AL_YR 0x2F
-#define MENELAUS_RTC_COMP_MSB 0x30
-#define MENELAUS_RTC_COMP_LSB 0x31
-#define MENELAUS_S1_PULL_EN 0x32
-#define MENELAUS_S1_PULL_DIR 0x33
-#define MENELAUS_S2_PULL_EN 0x34
-#define MENELAUS_S2_PULL_DIR 0x35
-#define MENELAUS_MCT_CTRL1 0x36
-#define MENELAUS_MCT_CTRL2 0x37
-#define MENELAUS_MCT_CTRL3 0x38
-#define MENELAUS_MCT_PIN_ST 0x39
-#define MENELAUS_DEBOUNCE1 0x3A
-
-#define IH_MENELAUS_IRQS 12
-#define MENELAUS_MMC_S1CD_IRQ 0 /* MMC slot 1 card change */
-#define MENELAUS_MMC_S2CD_IRQ 1 /* MMC slot 2 card change */
-#define MENELAUS_MMC_S1D1_IRQ 2 /* MMC DAT1 low in slot 1 */
-#define MENELAUS_MMC_S2D1_IRQ 3 /* MMC DAT1 low in slot 2 */
-#define MENELAUS_LOWBAT_IRQ 4 /* Low battery */
-#define MENELAUS_HOTDIE_IRQ 5 /* Hot die detect */
-#define MENELAUS_UVLO_IRQ 6 /* UVLO detect */
-#define MENELAUS_TSHUT_IRQ 7 /* Thermal shutdown */
-#define MENELAUS_RTCTMR_IRQ 8 /* RTC timer */
-#define MENELAUS_RTCALM_IRQ 9 /* RTC alarm */
-#define MENELAUS_RTCERR_IRQ 10 /* RTC error */
-#define MENELAUS_PSHBTN_IRQ 11 /* Push button */
-#define MENELAUS_RESERVED12_IRQ 12 /* Reserved */
-#define MENELAUS_RESERVED13_IRQ 13 /* Reserved */
-#define MENELAUS_RESERVED14_IRQ 14 /* Reserved */
-#define MENELAUS_RESERVED15_IRQ 15 /* Reserved */
-
-static void menelaus_work(struct work_struct *_menelaus);
-
-struct menelaus_chip {
- struct mutex lock;
- struct i2c_client *client;
- struct work_struct work;
-#ifdef CONFIG_RTC_DRV_TWL92330
- struct rtc_device *rtc;
- u8 rtc_control;
- unsigned uie:1;
-#endif
- unsigned vcore_hw_mode:1;
- u8 mask1, mask2;
- void (*handlers[16])(struct menelaus_chip *);
- void (*mmc_callback)(void *data, u8 mask);
- void *mmc_callback_data;
-};
-
-static struct menelaus_chip *the_menelaus;
-
-static int menelaus_write_reg(int reg, u8 value)
-{
- int val = i2c_smbus_write_byte_data(the_menelaus->client, reg, value);
-
- if (val < 0) {
- pr_err(DRIVER_NAME ": write error");
- return val;
- }
-
- return 0;
-}
-
-static int menelaus_read_reg(int reg)
-{
- int val = i2c_smbus_read_byte_data(the_menelaus->client, reg);
-
- if (val < 0)
- pr_err(DRIVER_NAME ": read error");
-
- return val;
-}
-
-static int menelaus_enable_irq(int irq)
-{
- if (irq > 7) {
- irq -= 8;
- the_menelaus->mask2 &= ~(1 << irq);
- return menelaus_write_reg(MENELAUS_INT_MASK2,
- the_menelaus->mask2);
- } else {
- the_menelaus->mask1 &= ~(1 << irq);
- return menelaus_write_reg(MENELAUS_INT_MASK1,
- the_menelaus->mask1);
- }
-}
-
-static int menelaus_disable_irq(int irq)
-{
- if (irq > 7) {
- irq -= 8;
- the_menelaus->mask2 |= (1 << irq);
- return menelaus_write_reg(MENELAUS_INT_MASK2,
- the_menelaus->mask2);
- } else {
- the_menelaus->mask1 |= (1 << irq);
- return menelaus_write_reg(MENELAUS_INT_MASK1,
- the_menelaus->mask1);
- }
-}
-
-static int menelaus_ack_irq(int irq)
-{
- if (irq > 7)
- return menelaus_write_reg(MENELAUS_INT_ACK2, 1 << (irq - 8));
- else
- return menelaus_write_reg(MENELAUS_INT_ACK1, 1 << irq);
-}
-
-/* Adds a handler for an interrupt. Does not run in interrupt context */
-static int menelaus_add_irq_work(int irq,
- void (*handler)(struct menelaus_chip *))
-{
- int ret = 0;
-
- mutex_lock(&the_menelaus->lock);
- the_menelaus->handlers[irq] = handler;
- ret = menelaus_enable_irq(irq);
- mutex_unlock(&the_menelaus->lock);
-
- return ret;
-}
-
-/* Removes handler for an interrupt */
-static int menelaus_remove_irq_work(int irq)
-{
- int ret = 0;
-
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_disable_irq(irq);
- the_menelaus->handlers[irq] = NULL;
- mutex_unlock(&the_menelaus->lock);
-
- return ret;
-}
-
-/*
- * Gets scheduled when a card detect interrupt happens. Note that in some cases
- * this line is wired to card cover switch rather than the card detect switch
- * in each slot. In this case the cards are not seen by menelaus.
- * FIXME: Add handling for D1 too
- */
-static void menelaus_mmc_cd_work(struct menelaus_chip *menelaus_hw)
-{
- int reg;
- unsigned char card_mask = 0;
-
- reg = menelaus_read_reg(MENELAUS_MCT_PIN_ST);
- if (reg < 0)
- return;
-
- if (!(reg & 0x1))
- card_mask |= (1 << 0);
-
- if (!(reg & 0x2))
- card_mask |= (1 << 1);
-
- if (menelaus_hw->mmc_callback)
- menelaus_hw->mmc_callback(menelaus_hw->mmc_callback_data,
- card_mask);
-}
-
-/*
- * Toggles the MMC slots between open-drain and push-pull mode.
- */
-int menelaus_set_mmc_opendrain(int slot, int enable)
-{
- int ret, val;
-
- if (slot != 1 && slot != 2)
- return -EINVAL;
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_read_reg(MENELAUS_MCT_CTRL1);
- if (ret < 0) {
- mutex_unlock(&the_menelaus->lock);
- return ret;
- }
- val = ret;
- if (slot == 1) {
- if (enable)
- val |= 1 << 2;
- else
- val &= ~(1 << 2);
- } else {
- if (enable)
- val |= 1 << 3;
- else
- val &= ~(1 << 3);
- }
- ret = menelaus_write_reg(MENELAUS_MCT_CTRL1, val);
- mutex_unlock(&the_menelaus->lock);
-
- return ret;
-}
-EXPORT_SYMBOL(menelaus_set_mmc_opendrain);
-
-int menelaus_set_slot_sel(int enable)
-{
- int ret;
-
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
- if (ret < 0)
- goto out;
- ret |= 0x02;
- if (enable)
- ret |= 1 << 5;
- else
- ret &= ~(1 << 5);
- ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
-out:
- mutex_unlock(&the_menelaus->lock);
- return ret;
-}
-EXPORT_SYMBOL(menelaus_set_slot_sel);
-
-int menelaus_set_mmc_slot(int slot, int enable, int power, int cd_en)
-{
- int ret, val;
-
- if (slot != 1 && slot != 2)
- return -EINVAL;
- if (power >= 3)
- return -EINVAL;
-
- mutex_lock(&the_menelaus->lock);
-
- ret = menelaus_read_reg(MENELAUS_MCT_CTRL2);
- if (ret < 0)
- goto out;
- val = ret;
- if (slot == 1) {
- if (cd_en)
- val |= (1 << 4) | (1 << 6);
- else
- val &= ~((1 << 4) | (1 << 6));
- } else {
- if (cd_en)
- val |= (1 << 5) | (1 << 7);
- else
- val &= ~((1 << 5) | (1 << 7));
- }
- ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, val);
- if (ret < 0)
- goto out;
-
- ret = menelaus_read_reg(MENELAUS_MCT_CTRL3);
- if (ret < 0)
- goto out;
- val = ret;
- if (slot == 1) {
- if (enable)
- val |= 1 << 0;
- else
- val &= ~(1 << 0);
- } else {
- int b;
-
- if (enable)
- ret |= 1 << 1;
- else
- ret &= ~(1 << 1);
- b = menelaus_read_reg(MENELAUS_MCT_CTRL2);
- b &= ~0x03;
- b |= power;
- ret = menelaus_write_reg(MENELAUS_MCT_CTRL2, b);
- if (ret < 0)
- goto out;
- }
- /* Disable autonomous shutdown */
- val &= ~(0x03 << 2);
- ret = menelaus_write_reg(MENELAUS_MCT_CTRL3, val);
-out:
- mutex_unlock(&the_menelaus->lock);
- return ret;
-}
-EXPORT_SYMBOL(menelaus_set_mmc_slot);
-
-int menelaus_register_mmc_callback(void (*callback)(void *data, u8 card_mask),
- void *data)
-{
- int ret = 0;
-
- the_menelaus->mmc_callback_data = data;
- the_menelaus->mmc_callback = callback;
- ret = menelaus_add_irq_work(MENELAUS_MMC_S1CD_IRQ,
- menelaus_mmc_cd_work);
- if (ret < 0)
- return ret;
- ret = menelaus_add_irq_work(MENELAUS_MMC_S2CD_IRQ,
- menelaus_mmc_cd_work);
- if (ret < 0)
- return ret;
- ret = menelaus_add_irq_work(MENELAUS_MMC_S1D1_IRQ,
- menelaus_mmc_cd_work);
- if (ret < 0)
- return ret;
- ret = menelaus_add_irq_work(MENELAUS_MMC_S2D1_IRQ,
- menelaus_mmc_cd_work);
-
- return ret;
-}
-EXPORT_SYMBOL(menelaus_register_mmc_callback);
-
-void menelaus_unregister_mmc_callback(void)
-{
- menelaus_remove_irq_work(MENELAUS_MMC_S1CD_IRQ);
- menelaus_remove_irq_work(MENELAUS_MMC_S2CD_IRQ);
- menelaus_remove_irq_work(MENELAUS_MMC_S1D1_IRQ);
- menelaus_remove_irq_work(MENELAUS_MMC_S2D1_IRQ);
-
- the_menelaus->mmc_callback = NULL;
- the_menelaus->mmc_callback_data = 0;
-}
-EXPORT_SYMBOL(menelaus_unregister_mmc_callback);
-
-struct menelaus_vtg {
- const char *name;
- u8 vtg_reg;
- u8 vtg_shift;
- u8 vtg_bits;
- u8 mode_reg;
-};
-
-struct menelaus_vtg_value {
- u16 vtg;
- u16 val;
-};
-
-static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV,
- int vtg_val, int mode)
-{
- int val, ret;
- struct i2c_client *c = the_menelaus->client;
-
- mutex_lock(&the_menelaus->lock);
- if (vtg == 0)
- goto set_voltage;
-
- ret = menelaus_read_reg(vtg->vtg_reg);
- if (ret < 0)
- goto out;
- val = ret & ~(((1 << vtg->vtg_bits) - 1) << vtg->vtg_shift);
- val |= vtg_val << vtg->vtg_shift;
-
- dev_dbg(&c->dev, "Setting voltage '%s'"
- "to %d mV (reg 0x%02x, val 0x%02x)\n",
- vtg->name, mV, vtg->vtg_reg, val);
-
- ret = menelaus_write_reg(vtg->vtg_reg, val);
- if (ret < 0)
- goto out;
-set_voltage:
- ret = menelaus_write_reg(vtg->mode_reg, mode);
-out:
- mutex_unlock(&the_menelaus->lock);
- if (ret == 0) {
- /* Wait for voltage to stabilize */
- msleep(1);
- }
- return ret;
-}
-
-static int menelaus_get_vtg_value(int vtg, const struct menelaus_vtg_value *tbl,
- int n)
-{
- int i;
-
- for (i = 0; i < n; i++, tbl++)
- if (tbl->vtg == vtg)
- return tbl->val;
- return -EINVAL;
-}
-
-/*
- * Vcore can be programmed in two ways:
- * SW-controlled: Required voltage is programmed into VCORE_CTRL1
- * HW-controlled: Required range (roof-floor) is programmed into VCORE_CTRL3
- * and VCORE_CTRL4
- *
- * Call correct 'set' function accordingly
- */
-
-static const struct menelaus_vtg_value vcore_values[] = {
- { 1000, 0 },
- { 1025, 1 },
- { 1050, 2 },
- { 1075, 3 },
- { 1100, 4 },
- { 1125, 5 },
- { 1150, 6 },
- { 1175, 7 },
- { 1200, 8 },
- { 1225, 9 },
- { 1250, 10 },
- { 1275, 11 },
- { 1300, 12 },
- { 1325, 13 },
- { 1350, 14 },
- { 1375, 15 },
- { 1400, 16 },
- { 1425, 17 },
- { 1450, 18 },
-};
-
-int menelaus_set_vcore_sw(unsigned int mV)
-{
- int val, ret;
- struct i2c_client *c = the_menelaus->client;
-
- val = menelaus_get_vtg_value(mV, vcore_values,
- ARRAY_SIZE(vcore_values));
- if (val < 0)
- return -EINVAL;
-
- dev_dbg(&c->dev, "Setting VCORE to %d mV (val 0x%02x)\n", mV, val);
-
- /* Set SW mode and the voltage in one go. */
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
- if (ret == 0)
- the_menelaus->vcore_hw_mode = 0;
- mutex_unlock(&the_menelaus->lock);
- msleep(1);
-
- return ret;
-}
-
-int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
-{
- int fval, rval, val, ret;
- struct i2c_client *c = the_menelaus->client;
-
- rval = menelaus_get_vtg_value(roof_mV, vcore_values,
- ARRAY_SIZE(vcore_values));
- if (rval < 0)
- return -EINVAL;
- fval = menelaus_get_vtg_value(floor_mV, vcore_values,
- ARRAY_SIZE(vcore_values));
- if (fval < 0)
- return -EINVAL;
-
- dev_dbg(&c->dev, "Setting VCORE FLOOR to %d mV and ROOF to %d mV\n",
- floor_mV, roof_mV);
-
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_write_reg(MENELAUS_VCORE_CTRL3, fval);
- if (ret < 0)
- goto out;
- ret = menelaus_write_reg(MENELAUS_VCORE_CTRL4, rval);
- if (ret < 0)
- goto out;
- if (!the_menelaus->vcore_hw_mode) {
- val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
- /* HW mode, turn OFF byte comparator */
- val |= ((1 << 7) | (1 << 5));
- ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
- the_menelaus->vcore_hw_mode = 1;
- }
- msleep(1);
-out:
- mutex_unlock(&the_menelaus->lock);
- return ret;
-}
-
-static const struct menelaus_vtg vmem_vtg = {
- .name = "VMEM",
- .vtg_reg = MENELAUS_LDO_CTRL1,
- .vtg_shift = 0,
- .vtg_bits = 2,
- .mode_reg = MENELAUS_LDO_CTRL3,
-};
-
-static const struct menelaus_vtg_value vmem_values[] = {
- { 1500, 0 },
- { 1800, 1 },
- { 1900, 2 },
- { 2500, 3 },
-};
-
-int menelaus_set_vmem(unsigned int mV)
-{
- int val;
-
- if (mV == 0)
- return menelaus_set_voltage(&vmem_vtg, 0, 0, 0);
-
- val = menelaus_get_vtg_value(mV, vmem_values, ARRAY_SIZE(vmem_values));
- if (val < 0)
- return -EINVAL;
- return menelaus_set_voltage(&vmem_vtg, mV, val, 0x02);
-}
-EXPORT_SYMBOL(menelaus_set_vmem);
-
-static const struct menelaus_vtg vio_vtg = {
- .name = "VIO",
- .vtg_reg = MENELAUS_LDO_CTRL1,
- .vtg_shift = 2,
- .vtg_bits = 2,
- .mode_reg = MENELAUS_LDO_CTRL4,
-};
-
-static const struct menelaus_vtg_value vio_values[] = {
- { 1500, 0 },
- { 1800, 1 },
- { 2500, 2 },
- { 2800, 3 },
-};
-
-int menelaus_set_vio(unsigned int mV)
-{
- int val;
-
- if (mV == 0)
- return menelaus_set_voltage(&vio_vtg, 0, 0, 0);
-
- val = menelaus_get_vtg_value(mV, vio_values, ARRAY_SIZE(vio_values));
- if (val < 0)
- return -EINVAL;
- return menelaus_set_voltage(&vio_vtg, mV, val, 0x02);
-}
-EXPORT_SYMBOL(menelaus_set_vio);
-
-static const struct menelaus_vtg_value vdcdc_values[] = {
- { 1500, 0 },
- { 1800, 1 },
- { 2000, 2 },
- { 2200, 3 },
- { 2400, 4 },
- { 2800, 5 },
- { 3000, 6 },
- { 3300, 7 },
-};
-
-static const struct menelaus_vtg vdcdc2_vtg = {
- .name = "VDCDC2",
- .vtg_reg = MENELAUS_DCDC_CTRL1,
- .vtg_shift = 0,
- .vtg_bits = 3,
- .mode_reg = MENELAUS_DCDC_CTRL2,
-};
-
-static const struct menelaus_vtg vdcdc3_vtg = {
- .name = "VDCDC3",
- .vtg_reg = MENELAUS_DCDC_CTRL1,
- .vtg_shift = 3,
- .vtg_bits = 3,
- .mode_reg = MENELAUS_DCDC_CTRL3,
-};
-
-int menelaus_set_vdcdc(int dcdc, unsigned int mV)
-{
- const struct menelaus_vtg *vtg;
- int val;
-
- if (dcdc != 2 && dcdc != 3)
- return -EINVAL;
- if (dcdc == 2)
- vtg = &vdcdc2_vtg;
- else
- vtg = &vdcdc3_vtg;
-
- if (mV == 0)
- return menelaus_set_voltage(vtg, 0, 0, 0);
-
- val = menelaus_get_vtg_value(mV, vdcdc_values,
- ARRAY_SIZE(vdcdc_values));
- if (val < 0)
- return -EINVAL;
- return menelaus_set_voltage(vtg, mV, val, 0x03);
-}
-
-static const struct menelaus_vtg_value vmmc_values[] = {
- { 1850, 0 },
- { 2800, 1 },
- { 3000, 2 },
- { 3100, 3 },
-};
-
-static const struct menelaus_vtg vmmc_vtg = {
- .name = "VMMC",
- .vtg_reg = MENELAUS_LDO_CTRL1,
- .vtg_shift = 6,
- .vtg_bits = 2,
- .mode_reg = MENELAUS_LDO_CTRL7,
-};
-
-int menelaus_set_vmmc(unsigned int mV)
-{
- int val;
-
- if (mV == 0)
- return menelaus_set_voltage(&vmmc_vtg, 0, 0, 0);
-
- val = menelaus_get_vtg_value(mV, vmmc_values, ARRAY_SIZE(vmmc_values));
- if (val < 0)
- return -EINVAL;
- return menelaus_set_voltage(&vmmc_vtg, mV, val, 0x02);
-}
-EXPORT_SYMBOL(menelaus_set_vmmc);
-
-
-static const struct menelaus_vtg_value vaux_values[] = {
- { 1500, 0 },
- { 1800, 1 },
- { 2500, 2 },
- { 2800, 3 },
-};
-
-static const struct menelaus_vtg vaux_vtg = {
- .name = "VAUX",
- .vtg_reg = MENELAUS_LDO_CTRL1,
- .vtg_shift = 4,
- .vtg_bits = 2,
- .mode_reg = MENELAUS_LDO_CTRL6,
-};
-
-int menelaus_set_vaux(unsigned int mV)
-{
- int val;
-
- if (mV == 0)
- return menelaus_set_voltage(&vaux_vtg, 0, 0, 0);
-
- val = menelaus_get_vtg_value(mV, vaux_values, ARRAY_SIZE(vaux_values));
- if (val < 0)
- return -EINVAL;
- return menelaus_set_voltage(&vaux_vtg, mV, val, 0x02);
-}
-EXPORT_SYMBOL(menelaus_set_vaux);
-
-int menelaus_get_slot_pin_states(void)
-{
- return menelaus_read_reg(MENELAUS_MCT_PIN_ST);
-}
-EXPORT_SYMBOL(menelaus_get_slot_pin_states);
-
-int menelaus_set_regulator_sleep(int enable, u32 val)
-{
- int t, ret;
- struct i2c_client *c = the_menelaus->client;
-
- mutex_lock(&the_menelaus->lock);
- ret = menelaus_write_reg(MENELAUS_SLEEP_CTRL2, val);
- if (ret < 0)
- goto out;
-
- dev_dbg(&c->dev, "regulator sleep configuration: %02x\n", val);
-
- ret = menelaus_read_reg(MENELAUS_GPIO_CTRL);
- if (ret < 0)
- goto out;
- t = ((1 << 6) | 0x04);
- if (enable)
- ret |= t;
- else
- ret &= ~t;
- ret = menelaus_write_reg(MENELAUS_GPIO_CTRL, ret);
-out:
- mutex_unlock(&the_menelaus->lock);
- return ret;
-}
-
-/*-----------------------------------------------------------------------*/
-
-/* Handles Menelaus interrupts. Does not run in interrupt context */
-static void menelaus_work(struct work_struct *_menelaus)
-{
- struct menelaus_chip *menelaus =
- container_of(_menelaus, struct menelaus_chip, work);
- void (*handler)(struct menelaus_chip *menelaus);
-
- while (1) {
- unsigned isr;
-
- isr = (menelaus_read_reg(MENELAUS_INT_STATUS2)
- & ~menelaus->mask2) << 8;
- isr |= menelaus_read_reg(MENELAUS_INT_STATUS1)
- & ~menelaus->mask1;
- if (!isr)
- break;
-
- while (isr) {
- int irq = fls(isr) - 1;
- isr &= ~(1 << irq);
-
- mutex_lock(&menelaus->lock);
- menelaus_disable_irq(irq);
- menelaus_ack_irq(irq);
- handler = menelaus->handlers[irq];
- if (handler)
- handler(menelaus);
- menelaus_enable_irq(irq);
- mutex_unlock(&menelaus->lock);
- }
- }
- enable_irq(menelaus->client->irq);
-}
-
-/*
- * We cannot use I2C in interrupt context, so we just schedule work.
- */
-static irqreturn_t menelaus_irq(int irq, void *_menelaus)
-{
- struct menelaus_chip *menelaus = _menelaus;
-
- disable_irq_nosync(irq);
- (void)schedule_work(&menelaus->work);
-
- return IRQ_HANDLED;
-}
-
-/*-----------------------------------------------------------------------*/
-
-/*
- * The RTC needs to be set once, then it runs on backup battery power.
- * It supports alarms, including system wake alarms (from some modes);
- * and 1/second IRQs if requested.
- */
-#ifdef CONFIG_RTC_DRV_TWL92330
-
-#define RTC_CTRL_RTC_EN (1 << 0)
-#define RTC_CTRL_AL_EN (1 << 1)
-#define RTC_CTRL_MODE12 (1 << 2)
-#define RTC_CTRL_EVERY_MASK (3 << 3)
-#define RTC_CTRL_EVERY_SEC (0 << 3)
-#define RTC_CTRL_EVERY_MIN (1 << 3)
-#define RTC_CTRL_EVERY_HR (2 << 3)
-#define RTC_CTRL_EVERY_DAY (3 << 3)
-
-#define RTC_UPDATE_EVERY 0x08
-
-#define RTC_HR_PM (1 << 7)
-
-static void menelaus_to_time(char *regs, struct rtc_time *t)
-{
- t->tm_sec = BCD2BIN(regs[0]);
- t->tm_min = BCD2BIN(regs[1]);
- if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
- t->tm_hour = BCD2BIN(regs[2] & 0x1f) - 1;
- if (regs[2] & RTC_HR_PM)
- t->tm_hour += 12;
- } else
- t->tm_hour = BCD2BIN(regs[2] & 0x3f);
- t->tm_mday = BCD2BIN(regs[3]);
- t->tm_mon = BCD2BIN(regs[4]) - 1;
- t->tm_year = BCD2BIN(regs[5]) + 100;
-}
-
-static int time_to_menelaus(struct rtc_time *t, int regnum)
-{
- int hour, status;
-
- status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_sec));
- if (status < 0)
- goto fail;
-
- status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_min));
- if (status < 0)
- goto fail;
-
- if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
- hour = t->tm_hour + 1;
- if (hour > 12)
- hour = RTC_HR_PM | BIN2BCD(hour - 12);
- else
- hour = BIN2BCD(hour);
- } else
- hour = BIN2BCD(t->tm_hour);
- status = menelaus_write_reg(regnum++, hour);
- if (status < 0)
- goto fail;
-
- status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_mday));
- if (status < 0)
- goto fail;
-
- status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_mon + 1));
- if (status < 0)
- goto fail;
-
- status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_year - 100));
- if (status < 0)
- goto fail;
-
- return 0;
-fail:
- dev_err(&the_menelaus->client->dev, "rtc write reg %02x, err %d\n",
- --regnum, status);
- return status;
-}
-
-static int menelaus_read_time(struct device *dev, struct rtc_time *t)
-{
- struct i2c_msg msg[2];
- char regs[7];
- int status;
-
- /* block read date and time registers */
- regs[0] = MENELAUS_RTC_SEC;
-
- msg[0].addr = MENELAUS_I2C_ADDRESS;
- msg[0].flags = 0;
- msg[0].len = 1;
- msg[0].buf = regs;
-
- msg[1].addr = MENELAUS_I2C_ADDRESS;
- msg[1].flags = I2C_M_RD;
- msg[1].len = sizeof(regs);
- msg[1].buf = regs;
-
- status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
- if (status != 2) {
- dev_err(dev, "%s error %d\n", "read", status);
- return -EIO;
- }
-
- menelaus_to_time(regs, t);
- t->tm_wday = BCD2BIN(regs[6]);
-
- return 0;
-}
-
-static int menelaus_set_time(struct device *dev, struct rtc_time *t)
-{
- int status;
-
- /* write date and time registers */
- status = time_to_menelaus(t, MENELAUS_RTC_SEC);
- if (status < 0)
- return status;
- status = menelaus_write_reg(MENELAUS_RTC_WKDAY, BIN2BCD(t->tm_wday));
- if (status < 0) {
- dev_err(&the_menelaus->client->dev, "rtc write reg %02x "
- "err %d\n", MENELAUS_RTC_WKDAY, status);
- return status;
- }
-
- /* now commit the write */
- status = menelaus_write_reg(MENELAUS_RTC_UPDATE, RTC_UPDATE_EVERY);
- if (status < 0)
- dev_err(&the_menelaus->client->dev, "rtc commit time, err %d\n",
- status);
-
- return 0;
-}
-
-static int menelaus_read_alarm(struct device *dev, struct rtc_wkalrm *w)
-{
- struct i2c_msg msg[2];
- char regs[6];
- int status;
-
- /* block read alarm registers */
- regs[0] = MENELAUS_RTC_AL_SEC;
-
- msg[0].addr = MENELAUS_I2C_ADDRESS;
- msg[0].flags = 0;
- msg[0].len = 1;
- msg[0].buf = regs;
-
- msg[1].addr = MENELAUS_I2C_ADDRESS;
- msg[1].flags = I2C_M_RD;
- msg[1].len = sizeof(regs);
- msg[1].buf = regs;
-
- status = i2c_transfer(the_menelaus->client->adapter, msg, 2);
- if (status != 2) {
- dev_err(dev, "%s error %d\n", "alarm read", status);
- return -EIO;
- }
-
- menelaus_to_time(regs, &w->time);
-
- w->enabled = !!(the_menelaus->rtc_control & RTC_CTRL_AL_EN);
-
- /* NOTE we *could* check if actually pending... */
- w->pending = 0;
-
- return 0;
-}
-
-static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w)
-{
- int status;
-
- if (the_menelaus->client->irq <= 0 && w->enabled)
- return -ENODEV;
-
- /* clear previous alarm enable */
- if (the_menelaus->rtc_control & RTC_CTRL_AL_EN) {
- the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
- status = menelaus_write_reg(MENELAUS_RTC_CTRL,
- the_menelaus->rtc_control);
- if (status < 0)
- return status;
- }
-
- /* write alarm registers */
- status = time_to_menelaus(&w->time, MENELAUS_RTC_AL_SEC);
- if (status < 0)
- return status;
-
- /* enable alarm if requested */
- if (w->enabled) {
- the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
- status = menelaus_write_reg(MENELAUS_RTC_CTRL,
- the_menelaus->rtc_control);
- }
-
- return status;
-}
-
-#ifdef CONFIG_RTC_INTF_DEV
-
-static void menelaus_rtc_update_work(struct menelaus_chip *m)
-{
- /* report 1/sec update */
- local_irq_disable();
- rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_UF);
- local_irq_enable();
-}
-
-static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
-{
- int status;
-
- if (the_menelaus->client->irq <= 0)
- return -ENOIOCTLCMD;
-
- switch (cmd) {
- /* alarm IRQ */
- case RTC_AIE_ON:
- if (the_menelaus->rtc_control & RTC_CTRL_AL_EN)
- return 0;
- the_menelaus->rtc_control |= RTC_CTRL_AL_EN;
- break;
- case RTC_AIE_OFF:
- if (!(the_menelaus->rtc_control & RTC_CTRL_AL_EN))
- return 0;
- the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
- break;
- /* 1/second "update" IRQ */
- case RTC_UIE_ON:
- if (the_menelaus->uie)
- return 0;
- status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
- status = menelaus_add_irq_work(MENELAUS_RTCTMR_IRQ,
- menelaus_rtc_update_work);
- if (status == 0)
- the_menelaus->uie = 1;
- return status;
- case RTC_UIE_OFF:
- if (!the_menelaus->uie)
- return 0;
- status = menelaus_remove_irq_work(MENELAUS_RTCTMR_IRQ);
- if (status == 0)
- the_menelaus->uie = 0;
- return status;
- default:
- return -ENOIOCTLCMD;
- }
- return menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
-}
-
-#else
-#define menelaus_ioctl NULL
-#endif
-
-/* REVISIT no compensation register support ... */
-
-static const struct rtc_class_ops menelaus_rtc_ops = {
- .ioctl = menelaus_ioctl,
- .read_time = menelaus_read_time,
- .set_time = menelaus_set_time,
- .read_alarm = menelaus_read_alarm,
- .set_alarm = menelaus_set_alarm,
-};
-
-static void menelaus_rtc_alarm_work(struct menelaus_chip *m)
-{
- /* report alarm */
- local_irq_disable();
- rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_AF);
- local_irq_enable();
-
- /* then disable it; alarms are oneshot */
- the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN;
- menelaus_write_reg(MENELAUS_RTC_CTRL, the_menelaus->rtc_control);
-}
-
-static inline void menelaus_rtc_init(struct menelaus_chip *m)
-{
- int alarm = (m->client->irq > 0);
-
- /* assume 32KDETEN pin is pulled high */
- if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) {
- dev_dbg(&m->client->dev, "no 32k oscillator\n");
- return;
- }
-
- /* support RTC alarm; it can issue wakeups */
- if (alarm) {
- if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ,
- menelaus_rtc_alarm_work) < 0) {
- dev_err(&m->client->dev, "can't handle RTC alarm\n");
- return;
- }
- device_init_wakeup(&m->client->dev, 1);
- }
-
- /* be sure RTC is enabled; allow 1/sec irqs; leave 12hr mode alone */
- m->rtc_control = menelaus_read_reg(MENELAUS_RTC_CTRL);
- if (!(m->rtc_control & RTC_CTRL_RTC_EN)
- || (m->rtc_control & RTC_CTRL_AL_EN)
- || (m->rtc_control & RTC_CTRL_EVERY_MASK)) {
- if (!(m->rtc_control & RTC_CTRL_RTC_EN)) {
- dev_warn(&m->client->dev, "rtc clock needs setting\n");
- m->rtc_control |= RTC_CTRL_RTC_EN;
- }
- m->rtc_control &= ~RTC_CTRL_EVERY_MASK;
- m->rtc_control &= ~RTC_CTRL_AL_EN;
- menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control);
- }
-
- m->rtc = rtc_device_register(DRIVER_NAME,
- &m->client->dev,
- &menelaus_rtc_ops, THIS_MODULE);
- if (IS_ERR(m->rtc)) {
- if (alarm) {
- menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ);
- device_init_wakeup(&m->client->dev, 0);
- }
- dev_err(&m->client->dev, "can't register RTC: %d\n",
- (int) PTR_ERR(m->rtc));
- the_menelaus->rtc = NULL;
- }
-}
-
-#else
-
-static inline void menelaus_rtc_init(struct menelaus_chip *m)
-{
- /* nothing */
-}
-
-#endif
-
-/*-----------------------------------------------------------------------*/
-
-static struct i2c_driver menelaus_i2c_driver;
-
-static int menelaus_probe(struct i2c_client *client)
-{
- struct menelaus_chip *menelaus;
- int rev = 0, val;
- int err = 0;
- struct menelaus_platform_data *menelaus_pdata =
- client->dev.platform_data;
-
- if (the_menelaus) {
- dev_dbg(&client->dev, "only one %s for now\n",
- DRIVER_NAME);
- return -ENODEV;
- }
-
- menelaus = kzalloc(sizeof *menelaus, GFP_KERNEL);
- if (!menelaus)
- return -ENOMEM;
-
- i2c_set_clientdata(client, menelaus);
-
- the_menelaus = menelaus;
- menelaus->client = client;
-
- /* If a true probe check the device */
- rev = menelaus_read_reg(MENELAUS_REV);
- if (rev < 0) {
- pr_err(DRIVER_NAME ": device not found");
- err = -ENODEV;
- goto fail1;
- }
-
- /* Ack and disable all Menelaus interrupts */
- menelaus_write_reg(MENELAUS_INT_ACK1, 0xff);
- menelaus_write_reg(MENELAUS_INT_ACK2, 0xff);
- menelaus_write_reg(MENELAUS_INT_MASK1, 0xff);
- menelaus_write_reg(MENELAUS_INT_MASK2, 0xff);
- menelaus->mask1 = 0xff;
- menelaus->mask2 = 0xff;
-
- /* Set output buffer strengths */
- menelaus_write_reg(MENELAUS_MCT_CTRL1, 0x73);
-
- if (client->irq > 0) {
- err = request_irq(client->irq, menelaus_irq, IRQF_DISABLED,
- DRIVER_NAME, menelaus);
- if (err) {
- dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
- client->irq, err);
- goto fail1;
- }
- }
-
- mutex_init(&menelaus->lock);
- INIT_WORK(&menelaus->work, menelaus_work);
-
- pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f);
-
- val = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
- if (val < 0)
- goto fail2;
- if (val & (1 << 7))
- menelaus->vcore_hw_mode = 1;
- else
- menelaus->vcore_hw_mode = 0;
-
- if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) {
- err = menelaus_pdata->late_init(&client->dev);
- if (err < 0)
- goto fail2;
- }
-
- menelaus_rtc_init(menelaus);
-
- return 0;
-fail2:
- free_irq(client->irq, menelaus);
- flush_scheduled_work();
-fail1:
- kfree(menelaus);
- return err;
-}
-
-static int __exit menelaus_remove(struct i2c_client *client)
-{
- struct menelaus_chip *menelaus = i2c_get_clientdata(client);
-
- free_irq(client->irq, menelaus);
- kfree(menelaus);
- i2c_set_clientdata(client, NULL);
- the_menelaus = NULL;
- return 0;
-}
-
-static struct i2c_driver menelaus_i2c_driver = {
- .driver = {
- .name = DRIVER_NAME,
- },
- .probe = menelaus_probe,
- .remove = __exit_p(menelaus_remove),
-};
-
-static int __init menelaus_init(void)
-{
- int res;
-
- res = i2c_add_driver(&menelaus_i2c_driver);
- if (res < 0) {
- pr_err(DRIVER_NAME ": driver registration failed\n");
- return res;
- }
-
- return 0;
-}
-
-static void __exit menelaus_exit(void)
-{
- i2c_del_driver(&menelaus_i2c_driver);
-
- /* FIXME: Shutdown menelaus parts that can be shut down */
-}
-
-MODULE_AUTHOR("Texas Instruments, Inc. (and others)");
-MODULE_DESCRIPTION("I2C interface for Menelaus.");
-MODULE_LICENSE("GPL");
-
-module_init(menelaus_init);
-module_exit(menelaus_exit);
diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c
deleted file mode 100644
index f43c4e79b55..00000000000
--- a/drivers/i2c/chips/pca9539.c
+++ /dev/null
@@ -1,196 +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 */
-static unsigned short normal_i2c[] = {0x74, 0x75, 0x76, 0x77, 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,
-};
-
-static int pca9539_attach_adapter(struct i2c_adapter *adapter);
-static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind);
-static int pca9539_detach_client(struct i2c_client *client);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver pca9539_driver = {
- .driver = {
- .name = "pca9539",
- },
- .attach_adapter = pca9539_attach_adapter,
- .detach_client = pca9539_detach_client,
-};
-
-struct pca9539_data {
- struct i2c_client client;
-};
-
-/* 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,
-};
-
-static int pca9539_attach_adapter(struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, pca9539_detect);
-}
-
-/* This function is called by i2c_probe */
-static int pca9539_detect(struct i2c_adapter *adapter, int address, int kind)
-{
- struct i2c_client *new_client;
- struct pca9539_data *data;
- int err = 0;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- goto exit;
-
- /* OK. For now, we presume we have a valid client. We now create the
- client structure, even though we cannot fill it completely yet. */
- if (!(data = kzalloc(sizeof(struct pca9539_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
-
- new_client = &data->client;
- i2c_set_clientdata(new_client, data);
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &pca9539_driver;
- new_client->flags = 0;
-
- if (kind < 0) {
- /* Detection: the pca9539 only has 8 registers (0-7).
- A read of 7 should succeed, but a read of 8 should fail. */
- if ((i2c_smbus_read_byte_data(new_client, 7) < 0) ||
- (i2c_smbus_read_byte_data(new_client, 8) >= 0))
- goto exit_kfree;
- }
-
- strlcpy(new_client->name, "pca9539", I2C_NAME_SIZE);
-
- /* Tell the I2C layer a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto exit_kfree;
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&new_client->dev.kobj,
- &pca9539_defattr_group);
- if (err)
- goto exit_detach;
-
- return 0;
-
-exit_detach:
- i2c_detach_client(new_client);
-exit_kfree:
- kfree(data);
-exit:
- return err;
-}
-
-static int pca9539_detach_client(struct i2c_client *client)
-{
- int err;
-
- sysfs_remove_group(&client->dev.kobj, &pca9539_defattr_group);
-
- if ((err = i2c_detach_client(client)))
- return err;
-
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-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 e5b31329b56..00000000000
--- a/drivers/i2c/chips/pcf8574.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- pcf8574.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- 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 */
-static const unsigned short normal_i2c[] = {
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- I2C_CLIENT_END
-};
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD_2(pcf8574, pcf8574a);
-
-/* Each client has this additional data */
-struct pcf8574_data {
- struct i2c_client client;
-
- int write; /* Remember last written value */
-};
-
-static int pcf8574_attach_adapter(struct i2c_adapter *adapter);
-static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind);
-static int pcf8574_detach_client(struct i2c_client *client);
-static void pcf8574_init_client(struct i2c_client *client);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver pcf8574_driver = {
- .driver = {
- .name = "pcf8574",
- },
- .attach_adapter = pcf8574_attach_adapter,
- .detach_client = pcf8574_detach_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
- */
-
-static int pcf8574_attach_adapter(struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, pcf8574_detect);
-}
-
-/* This function is called by i2c_probe */
-static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
-{
- struct i2c_client *new_client;
- struct pcf8574_data *data;
- int err = 0;
- const char *client_name = "";
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
- goto exit;
-
- /* OK. For now, we presume we have a valid client. We now create the
- client structure, even though we cannot fill it completely yet. */
- if (!(data = kzalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
-
- new_client = &data->client;
- i2c_set_clientdata(new_client, data);
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &pcf8574_driver;
- new_client->flags = 0;
-
- /* 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 (address >= 0x38 && address <= 0x3f)
- kind = pcf8574a;
- else
- kind = pcf8574;
- }
-
- if (kind == pcf8574a)
- client_name = "pcf8574a";
- else
- client_name = "pcf8574";
-
- /* Fill in the remaining client fields and put it into the global list */
- strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
-
- /* Tell the I2C layer a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto exit_free;
-
- /* Initialize the PCF8574 chip */
- pcf8574_init_client(new_client);
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&new_client->dev.kobj, &pcf8574_attr_group);
- if (err)
- goto exit_detach;
- return 0;
-
- exit_detach:
- i2c_detach_client(new_client);
- exit_free:
- kfree(data);
- exit:
- return err;
-}
-
-static int pcf8574_detach_client(struct i2c_client *client)
-{
- int err;
-
- sysfs_remove_group(&client->dev.kobj, &pcf8574_attr_group);
-
- if ((err = i2c_detach_client(client)))
- return err;
-
- 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 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 3ea08ac0bfa..00000000000
--- a/drivers/i2c/chips/pcf8575.c
+++ /dev/null
@@ -1,214 +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 */
-static const unsigned short normal_i2c[] = {
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- I2C_CLIENT_END
-};
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD;
-
-
-/* Each client has this additional data */
-struct pcf8575_data {
- struct i2c_client client;
- int write; /* last written value, or error code */
-};
-
-static int pcf8575_attach_adapter(struct i2c_adapter *adapter);
-static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind);
-static int pcf8575_detach_client(struct i2c_client *client);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver pcf8575_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "pcf8575",
- },
- .attach_adapter = pcf8575_attach_adapter,
- .detach_client = pcf8575_detach_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);
- 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
- */
-
-static int pcf8575_attach_adapter(struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, pcf8575_detect);
-}
-
-/* This function is called by i2c_probe */
-static int pcf8575_detect(struct i2c_adapter *adapter, int address, int kind)
-{
- struct i2c_client *client;
- struct pcf8575_data *data;
- int err = 0;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
- goto exit;
-
- /* OK. For now, we presume we have a valid client. We now create the
- client structure, even though we cannot fill it completely yet. */
- data = kzalloc(sizeof(struct pcf8575_data), GFP_KERNEL);
- if (!data) {
- err = -ENOMEM;
- goto exit;
- }
-
- client = &data->client;
- i2c_set_clientdata(client, data);
- client->addr = address;
- client->adapter = adapter;
- client->driver = &pcf8575_driver;
- strlcpy(client->name, "pcf8575", I2C_NAME_SIZE);
- data->write = -EAGAIN;
-
- /* 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. */
-
- /* Tell the I2C layer a new client has arrived */
- err = i2c_attach_client(client);
- if (err)
- goto exit_free;
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&client->dev.kobj, &pcf8575_attr_group);
- if (err)
- goto exit_detach;
-
- return 0;
-
-exit_detach:
- i2c_detach_client(client);
-exit_free:
- kfree(data);
-exit:
- return err;
-}
-
-static int pcf8575_detach_client(struct i2c_client *client)
-{
- int err;
-
- sysfs_remove_group(&client->dev.kobj, &pcf8575_attr_group);
-
- err = i2c_detach_client(client);
- if (err)
- return err;
-
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-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 66c7c3bb942..00000000000
--- a/drivers/i2c/chips/pcf8591.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- pcf8591.c - Part of lm_sensors, Linux kernel modules for hardware
- monitoring
- 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 i2c_client client;
- struct mutex update_lock;
-
- u8 control;
- u8 aout;
-};
-
-static int pcf8591_attach_adapter(struct i2c_adapter *adapter);
-static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind);
-static int pcf8591_detach_client(struct i2c_client *client);
-static void pcf8591_init_client(struct i2c_client *client);
-static int pcf8591_read_channel(struct device *dev, int channel);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver pcf8591_driver = {
- .driver = {
- .name = "pcf8591",
- },
- .attach_adapter = pcf8591_attach_adapter,
- .detach_client = pcf8591_detach_client,
-};
-
-/* 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
- */
-static int pcf8591_attach_adapter(struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, pcf8591_detect);
-}
-
-/* This function is called by i2c_probe */
-static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
-{
- struct i2c_client *new_client;
- struct pcf8591_data *data;
- int err = 0;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE
- | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
- goto exit;
-
- /* OK. For now, we presume we have a valid client. We now create the
- client structure, even though we cannot fill it completely yet. */
- if (!(data = kzalloc(sizeof(struct pcf8591_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
-
- new_client = &data->client;
- i2c_set_clientdata(new_client, data);
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &pcf8591_driver;
- new_client->flags = 0;
-
- /* Now, we would do the remaining detection. But the PCF8591 is plainly
- impossible to detect! Stupid chip. */
-
- /* Determine the chip type - only one kind supported! */
- if (kind <= 0)
- kind = pcf8591;
-
- /* Fill in the remaining client fields and put it into the global
- list */
- strlcpy(new_client->name, "pcf8591", I2C_NAME_SIZE);
- mutex_init(&data->update_lock);
-
- /* Tell the I2C layer a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto exit_kfree;
-
- /* Initialize the PCF8591 chip */
- pcf8591_init_client(new_client);
-
- /* Register sysfs hooks */
- err = sysfs_create_group(&new_client->dev.kobj, &pcf8591_attr_group);
- if (err)
- goto exit_detach;
-
- /* Register input2 if not in "two differential inputs" mode */
- if (input_mode != 3) {
- if ((err = device_create_file(&new_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(&new_client->dev,
- &dev_attr_in3_input)))
- goto exit_sysfs_remove;
- }
-
- return 0;
-
-exit_sysfs_remove:
- sysfs_remove_group(&new_client->dev.kobj, &pcf8591_attr_group_opt);
- sysfs_remove_group(&new_client->dev.kobj, &pcf8591_attr_group);
-exit_detach:
- i2c_detach_client(new_client);
-exit_kfree:
- kfree(data);
-exit:
- return err;
-}
-
-static int pcf8591_detach_client(struct i2c_client *client)
-{
- int err;
-
- sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group_opt);
- sysfs_remove_group(&client->dev.kobj, &pcf8591_attr_group);
-
- if ((err = i2c_detach_client(client)))
- return err;
-
- 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 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/tps65010.c b/drivers/i2c/chips/tps65010.c
deleted file mode 100644
index 4154a910885..00000000000
--- a/drivers/i2c/chips/tps65010.c
+++ /dev/null
@@ -1,969 +0,0 @@
-/*
- * tps65010 - driver for tps6501x power management chips
- *
- * Copyright (C) 2004 Texas Instruments
- * Copyright (C) 2004-2005 David Brownell
- *
- * 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/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/delay.h>
-#include <linux/workqueue.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/mutex.h>
-
-#include <linux/i2c/tps65010.h>
-
-/*-------------------------------------------------------------------------*/
-
-#define DRIVER_VERSION "2 May 2005"
-#define DRIVER_NAME (tps65010_driver.driver.name)
-
-MODULE_DESCRIPTION("TPS6501x Power Management Driver");
-MODULE_LICENSE("GPL");
-
-static struct i2c_driver tps65010_driver;
-
-/*-------------------------------------------------------------------------*/
-
-/* This driver handles a family of multipurpose chips, which incorporate
- * voltage regulators, lithium ion/polymer battery charging, GPIOs, LEDs,
- * and other features often needed in portable devices like cell phones
- * or digital cameras.
- *
- * The tps65011 and tps65013 have different voltage settings compared
- * to tps65010 and tps65012. The tps65013 has a NO_CHG status/irq.
- * All except tps65010 have "wait" mode, possibly defaulted so that
- * battery-insert != device-on.
- *
- * We could distinguish between some models by checking VDCDC1.UVLO or
- * other registers, unless they've been changed already after powerup
- * as part of board setup by a bootloader.
- */
-enum tps_model {
- TPS_UNKNOWN = 0,
- TPS65010,
- TPS65011,
- TPS65012,
- TPS65013,
-};
-
-struct tps65010 {
- struct i2c_client *client;
- struct mutex lock;
- struct delayed_work work;
- struct dentry *file;
- unsigned charging:1;
- unsigned por:1;
- unsigned model:8;
- u16 vbus;
- unsigned long flags;
-#define FLAG_VBUS_CHANGED 0
-#define FLAG_IRQ_ENABLE 1
-
- /* copies of last register state */
- u8 chgstatus, regstatus, chgconf;
- u8 nmask1, nmask2;
-
- /* not currently tracking GPIO state */
-};
-
-#define POWER_POLL_DELAY msecs_to_jiffies(5000)
-
-/*-------------------------------------------------------------------------*/
-
-#if defined(DEBUG) || defined(CONFIG_DEBUG_FS)
-
-static void dbg_chgstat(char *buf, size_t len, u8 chgstatus)
-{
- snprintf(buf, len, "%02x%s%s%s%s%s%s%s%s\n",
- chgstatus,
- (chgstatus & TPS_CHG_USB) ? " USB" : "",
- (chgstatus & TPS_CHG_AC) ? " AC" : "",
- (chgstatus & TPS_CHG_THERM) ? " therm" : "",
- (chgstatus & TPS_CHG_TERM) ? " done" :
- ((chgstatus & (TPS_CHG_USB|TPS_CHG_AC))
- ? " (charging)" : ""),
- (chgstatus & TPS_CHG_TAPER_TMO) ? " taper_tmo" : "",
- (chgstatus & TPS_CHG_CHG_TMO) ? " charge_tmo" : "",
- (chgstatus & TPS_CHG_PRECHG_TMO) ? " prechg_tmo" : "",
- (chgstatus & TPS_CHG_TEMP_ERR) ? " temp_err" : "");
-}
-
-static void dbg_regstat(char *buf, size_t len, u8 regstatus)
-{
- snprintf(buf, len, "%02x %s%s%s%s%s%s%s%s\n",
- regstatus,
- (regstatus & TPS_REG_ONOFF) ? "off" : "(on)",
- (regstatus & TPS_REG_COVER) ? " uncover" : "",
- (regstatus & TPS_REG_UVLO) ? " UVLO" : "",
- (regstatus & TPS_REG_NO_CHG) ? " NO_CHG" : "",
- (regstatus & TPS_REG_PG_LD02) ? " ld02_bad" : "",
- (regstatus & TPS_REG_PG_LD01) ? " ld01_bad" : "",
- (regstatus & TPS_REG_PG_MAIN) ? " main_bad" : "",
- (regstatus & TPS_REG_PG_CORE) ? " core_bad" : "");
-}
-
-static void dbg_chgconf(int por, char *buf, size_t len, u8 chgconfig)
-{
- const char *hibit;
-
- if (por)
- hibit = (chgconfig & TPS_CHARGE_POR)
- ? "POR=69ms" : "POR=1sec";
- else
- hibit = (chgconfig & TPS65013_AUA) ? "AUA" : "";
-
- snprintf(buf, len, "%02x %s%s%s AC=%d%% USB=%dmA %sCharge\n",
- chgconfig, hibit,
- (chgconfig & TPS_CHARGE_RESET) ? " reset" : "",
- (chgconfig & TPS_CHARGE_FAST) ? " fast" : "",
- ({int p; switch ((chgconfig >> 3) & 3) {
- case 3: p = 100; break;
- case 2: p = 75; break;
- case 1: p = 50; break;
- default: p = 25; break;
- }; p; }),
- (chgconfig & TPS_VBUS_CHARGING)
- ? ((chgconfig & TPS_VBUS_500MA) ? 500 : 100)
- : 0,
- (chgconfig & TPS_CHARGE_ENABLE) ? "" : "No");
-}
-
-#endif
-
-#ifdef DEBUG
-
-static void show_chgstatus(const char *label, u8 chgstatus)
-{
- char buf [100];
-
- dbg_chgstat(buf, sizeof buf, chgstatus);
- pr_debug("%s: %s %s", DRIVER_NAME, label, buf);
-}
-
-static void show_regstatus(const char *label, u8 regstatus)
-{
- char buf [100];
-
- dbg_regstat(buf, sizeof buf, regstatus);
- pr_debug("%s: %s %s", DRIVER_NAME, label, buf);
-}
-
-static void show_chgconfig(int por, const char *label, u8 chgconfig)
-{
- char buf [100];
-
- dbg_chgconf(por, buf, sizeof buf, chgconfig);
- pr_debug("%s: %s %s", DRIVER_NAME, label, buf);
-}
-
-#else
-
-static inline void show_chgstatus(const char *label, u8 chgstatus) { }
-static inline void show_regstatus(const char *label, u8 chgstatus) { }
-static inline void show_chgconfig(int por, const char *label, u8 chgconfig) { }
-
-#endif
-
-#ifdef CONFIG_DEBUG_FS
-
-static int dbg_show(struct seq_file *s, void *_)
-{
- struct tps65010 *tps = s->private;
- u8 value, v2;
- unsigned i;
- char buf[100];
- const char *chip;
-
- switch (tps->model) {
- case TPS65010: chip = "tps65010"; break;
- case TPS65011: chip = "tps65011"; break;
- case TPS65012: chip = "tps65012"; break;
- case TPS65013: chip = "tps65013"; break;
- default: chip = NULL; break;
- }
- seq_printf(s, "driver %s\nversion %s\nchip %s\n\n",
- DRIVER_NAME, DRIVER_VERSION, chip);
-
- mutex_lock(&tps->lock);
-
- /* FIXME how can we tell whether a battery is present?
- * likely involves a charge gauging chip (like BQ26501).
- */
-
- seq_printf(s, "%scharging\n\n", tps->charging ? "" : "(not) ");
-
-
- /* registers for monitoring battery charging and status; note
- * that reading chgstat and regstat may ack IRQs...
- */
- value = i2c_smbus_read_byte_data(tps->client, TPS_CHGCONFIG);
- dbg_chgconf(tps->por, buf, sizeof buf, value);
- seq_printf(s, "chgconfig %s", buf);
-
- value = i2c_smbus_read_byte_data(tps->client, TPS_CHGSTATUS);
- dbg_chgstat(buf, sizeof buf, value);
- seq_printf(s, "chgstat %s", buf);
- value = i2c_smbus_read_byte_data(tps->client, TPS_MASK1);
- dbg_chgstat(buf, sizeof buf, value);
- seq_printf(s, "mask1 %s", buf);
- /* ignore ackint1 */
-
- value = i2c_smbus_read_byte_data(tps->client, TPS_REGSTATUS);
- dbg_regstat(buf, sizeof buf, value);
- seq_printf(s, "regstat %s", buf);
- value = i2c_smbus_read_byte_data(tps->client, TPS_MASK2);
- dbg_regstat(buf, sizeof buf, value);
- seq_printf(s, "mask2 %s\n", buf);
- /* ignore ackint2 */
-
- (void) schedule_delayed_work(&tps->work, POWER_POLL_DELAY);
-
-
- /* VMAIN voltage, enable lowpower, etc */
- value = i2c_smbus_read_byte_data(tps->client, TPS_VDCDC1);
- seq_printf(s, "vdcdc1 %02x\n", value);
-
- /* VCORE voltage, vibrator on/off */
- value = i2c_smbus_read_byte_data(tps->client, TPS_VDCDC2);
- seq_printf(s, "vdcdc2 %02x\n", value);
-
- /* both LD0s, and their lowpower behavior */
- value = i2c_smbus_read_byte_data(tps->client, TPS_VREGS1);
- seq_printf(s, "vregs1 %02x\n\n", value);
-
-
- /* LEDs and GPIOs */
- value = i2c_smbus_read_byte_data(tps->client, TPS_LED1_ON);
- v2 = i2c_smbus_read_byte_data(tps->client, TPS_LED1_PER);
- seq_printf(s, "led1 %s, on=%02x, per=%02x, %d/%d msec\n",
- (value & 0x80)
- ? ((v2 & 0x80) ? "on" : "off")
- : ((v2 & 0x80) ? "blink" : "(nPG)"),
- value, v2,
- (value & 0x7f) * 10, (v2 & 0x7f) * 100);
-
- value = i2c_smbus_read_byte_data(tps->client, TPS_LED2_ON);
- v2 = i2c_smbus_read_byte_data(tps->client, TPS_LED2_PER);
- seq_printf(s, "led2 %s, on=%02x, per=%02x, %d/%d msec\n",
- (value & 0x80)
- ? ((v2 & 0x80) ? "on" : "off")
- : ((v2 & 0x80) ? "blink" : "off"),
- value, v2,
- (value & 0x7f) * 10, (v2 & 0x7f) * 100);
-
- value = i2c_smbus_read_byte_data(tps->client, TPS_DEFGPIO);
- v2 = i2c_smbus_read_byte_data(tps->client, TPS_MASK3);
- seq_printf(s, "defgpio %02x mask3 %02x\n", value, v2);
-
- for (i = 0; i < 4; i++) {
- if (value & (1 << (4 + i)))
- seq_printf(s, " gpio%d-out %s\n", i + 1,
- (value & (1 << i)) ? "low" : "hi ");
- else
- seq_printf(s, " gpio%d-in %s %s %s\n", i + 1,
- (value & (1 << i)) ? "hi " : "low",
- (v2 & (1 << i)) ? "no-irq" : "irq",
- (v2 & (1 << (4 + i))) ? "rising" : "falling");
- }
-
- mutex_unlock(&tps->lock);
- return 0;
-}
-
-static int dbg_tps_open(struct inode *inode, struct file *file)
-{
- return single_open(file, dbg_show, inode->i_private);
-}
-
-static const struct file_operations debug_fops = {
- .open = dbg_tps_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-#define DEBUG_FOPS &debug_fops
-
-#else
-#define DEBUG_FOPS NULL
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-/* handle IRQS in a task context, so we can use I2C calls */
-static void tps65010_interrupt(struct tps65010 *tps)
-{
- u8 tmp = 0, mask, poll;
-
- /* IRQs won't trigger for certain events, but we can get
- * others by polling (normally, with external power applied).
- */
- poll = 0;
-
- /* regstatus irqs */
- if (tps->nmask2) {
- tmp = i2c_smbus_read_byte_data(tps->client, TPS_REGSTATUS);
- mask = tmp ^ tps->regstatus;
- tps->regstatus = tmp;
- mask &= tps->nmask2;
- } else
- mask = 0;
- if (mask) {
- tps->regstatus = tmp;
- /* may need to shut something down ... */
-
- /* "off" usually means deep sleep */
- if (tmp & TPS_REG_ONOFF) {
- pr_info("%s: power off button\n", DRIVER_NAME);
-#if 0
- /* REVISIT: this might need its own workqueue
- * plus tweaks including deadlock avoidance ...
- * also needs to get error handling and probably
- * an #ifdef CONFIG_HIBERNATION
- */
- hibernate();
-#endif
- poll = 1;
- }
- }
-
- /* chgstatus irqs */
- if (tps->nmask1) {
- tmp = i2c_smbus_read_byte_data(tps->client, TPS_CHGSTATUS);
- mask = tmp ^ tps->chgstatus;
- tps->chgstatus = tmp;
- mask &= tps->nmask1;
- } else
- mask = 0;
- if (mask) {
- unsigned charging = 0;
-
- show_chgstatus("chg/irq", tmp);
- if (tmp & (TPS_CHG_USB|TPS_CHG_AC))
- show_chgconfig(tps->por, "conf", tps->chgconf);
-
- /* Unless it was turned off or disabled, we charge any
- * battery whenever there's power available for it
- * and the charger hasn't been disabled.
- */
- if (!(tps->chgstatus & ~(TPS_CHG_USB|TPS_CHG_AC))
- && (tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC))
- && (tps->chgconf & TPS_CHARGE_ENABLE)
- ) {
- if (tps->chgstatus & TPS_CHG_USB) {
- /* VBUS options are readonly until reconnect */
- if (mask & TPS_CHG_USB)
- set_bit(FLAG_VBUS_CHANGED, &tps->flags);
- charging = 1;
- } else if (tps->chgstatus & TPS_CHG_AC)
- charging = 1;
- }
- if (charging != tps->charging) {
- tps->charging = charging;
- pr_info("%s: battery %scharging\n",
- DRIVER_NAME, charging ? "" :
- ((tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC))
- ? "NOT " : "dis"));
- }
- }
-
- /* always poll to detect (a) power removal, without tps65013
- * NO_CHG IRQ; or (b) restart of charging after stop.
- */
- if ((tps->model != TPS65013 || !tps->charging)
- && (tps->chgstatus & (TPS_CHG_USB|TPS_CHG_AC)))
- poll = 1;
- if (poll)
- (void) schedule_delayed_work(&tps->work, POWER_POLL_DELAY);
-
- /* also potentially gpio-in rise or fall */
-}
-
-/* handle IRQs and polling using keventd for now */
-static void tps65010_work(struct work_struct *work)
-{
- struct tps65010 *tps;
-
- tps = container_of(work, struct tps65010, work.work);
- mutex_lock(&tps->lock);
-
- tps65010_interrupt(tps);
-
- if (test_and_clear_bit(FLAG_VBUS_CHANGED, &tps->flags)) {
- int status;
- u8 chgconfig, tmp;
-
- chgconfig = i2c_smbus_read_byte_data(tps->client,
- TPS_CHGCONFIG);
- chgconfig &= ~(TPS_VBUS_500MA | TPS_VBUS_CHARGING);
- if (tps->vbus == 500)
- chgconfig |= TPS_VBUS_500MA | TPS_VBUS_CHARGING;
- else if (tps->vbus >= 100)
- chgconfig |= TPS_VBUS_CHARGING;
-
- status = i2c_smbus_write_byte_data(tps->client,
- TPS_CHGCONFIG, chgconfig);
-
- /* vbus update fails unless VBUS is connected! */
- tmp = i2c_smbus_read_byte_data(tps->client, TPS_CHGCONFIG);
- tps->chgconf = tmp;
- show_chgconfig(tps->por, "update vbus", tmp);
- }
-
- if (test_and_clear_bit(FLAG_IRQ_ENABLE, &tps->flags))
- enable_irq(tps->client->irq);
-
- mutex_unlock(&tps->lock);
-}
-
-static irqreturn_t tps65010_irq(int irq, void *_tps)
-{
- struct tps65010 *tps = _tps;
-
- disable_irq_nosync(irq);
- set_bit(FLAG_IRQ_ENABLE, &tps->flags);
- (void) schedule_work(&tps->work.work);
- return IRQ_HANDLED;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static struct tps65010 *the_tps;
-
-static int __exit tps65010_remove(struct i2c_client *client)
-{
- struct tps65010 *tps = i2c_get_clientdata(client);
-
- if (client->irq > 0)
- free_irq(client->irq, tps);
- cancel_delayed_work(&tps->work);
- flush_scheduled_work();
- debugfs_remove(tps->file);
- kfree(tps);
- the_tps = NULL;
- return 0;
-}
-
-static int tps65010_probe(struct i2c_client *client)
-{
- struct tps65010 *tps;
- int status;
-
- if (the_tps) {
- dev_dbg(&client->dev, "only one tps6501x chip allowed\n");
- return -ENODEV;
- }
-
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -EINVAL;
-
- tps = kzalloc(sizeof *tps, GFP_KERNEL);
- if (!tps)
- return -ENOMEM;
-
- mutex_init(&tps->lock);
- INIT_DELAYED_WORK(&tps->work, tps65010_work);
- tps->client = client;
-
- if (strcmp(client->name, "tps65010") == 0)
- tps->model = TPS65010;
- else if (strcmp(client->name, "tps65011") == 0)
- tps->model = TPS65011;
- else if (strcmp(client->name, "tps65012") == 0)
- tps->model = TPS65012;
- else if (strcmp(client->name, "tps65013") == 0)
- tps->model = TPS65013;
- else {
- dev_warn(&client->dev, "unknown chip '%s'\n", client->name);
- status = -ENODEV;
- goto fail1;
- }
-
- /* the IRQ is active low, but many gpio lines can't support that
- * so this driver uses falling-edge triggers instead.
- */
- if (client->irq > 0) {
- status = request_irq(client->irq, tps65010_irq,
- IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING,
- DRIVER_NAME, tps);
- if (status < 0) {
- dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
- client->irq, status);
- goto fail1;
- }
- /* annoying race here, ideally we'd have an option
- * to claim the irq now and enable it later.
- * FIXME genirq IRQF_NOAUTOEN now solves that ...
- */
- disable_irq(client->irq);
- set_bit(FLAG_IRQ_ENABLE, &tps->flags);
- } else
- dev_warn(&client->dev, "IRQ not configured!\n");
-
-
- switch (tps->model) {
- case TPS65010:
- case TPS65012:
- tps->por = 1;
- break;
- case TPS_UNKNOWN:
- printk(KERN_WARNING "%s: unknown TPS chip\n", DRIVER_NAME);
- break;
- /* else CHGCONFIG.POR is replaced by AUA, enabling a WAIT mode */
- }
- tps->chgconf = i2c_smbus_read_byte_data(client, TPS_CHGCONFIG);
- show_chgconfig(tps->por, "conf/init", tps->chgconf);
-
- show_chgstatus("chg/init",
- i2c_smbus_read_byte_data(client, TPS_CHGSTATUS));
- show_regstatus("reg/init",
- i2c_smbus_read_byte_data(client, TPS_REGSTATUS));
-
- pr_debug("%s: vdcdc1 0x%02x, vdcdc2 %02x, vregs1 %02x\n", DRIVER_NAME,
- i2c_smbus_read_byte_data(client, TPS_VDCDC1),
- i2c_smbus_read_byte_data(client, TPS_VDCDC2),
- i2c_smbus_read_byte_data(client, TPS_VREGS1));
- pr_debug("%s: defgpio 0x%02x, mask3 0x%02x\n", DRIVER_NAME,
- i2c_smbus_read_byte_data(client, TPS_DEFGPIO),
- i2c_smbus_read_byte_data(client, TPS_MASK3));
-
- the_tps = tps;
-
-#if defined(CONFIG_USB_GADGET) && !defined(CONFIG_USB_OTG)
- /* USB hosts can't draw VBUS. OTG devices could, later
- * when OTG infrastructure enables it. USB peripherals
- * could be relying on VBUS while booting, though.
- */
- tps->vbus = 100;
-#endif
-
- /* unmask the "interesting" irqs, then poll once to
- * kickstart monitoring, initialize shadowed status
- * registers, and maybe disable VBUS draw.
- */
- tps->nmask1 = ~0;
- (void) i2c_smbus_write_byte_data(client, TPS_MASK1, ~tps->nmask1);
-
- tps->nmask2 = TPS_REG_ONOFF;
- if (tps->model == TPS65013)
- tps->nmask2 |= TPS_REG_NO_CHG;
- (void) i2c_smbus_write_byte_data(client, TPS_MASK2, ~tps->nmask2);
-
- (void) i2c_smbus_write_byte_data(client, TPS_MASK3, 0x0f
- | i2c_smbus_read_byte_data(client, TPS_MASK3));
-
- tps65010_work(&tps->work.work);
-
- tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL,
- tps, DEBUG_FOPS);
- return 0;
-fail1:
- kfree(tps);
- return status;
-}
-
-static struct i2c_driver tps65010_driver = {
- .driver = {
- .name = "tps65010",
- },
- .probe = tps65010_probe,
- .remove = __exit_p(tps65010_remove),
-};
-
-/*-------------------------------------------------------------------------*/
-
-/* Draw from VBUS:
- * 0 mA -- DON'T DRAW (might supply power instead)
- * 100 mA -- usb unit load (slowest charge rate)
- * 500 mA -- usb high power (fast battery charge)
- */
-int tps65010_set_vbus_draw(unsigned mA)
-{
- unsigned long flags;
-
- if (!the_tps)
- return -ENODEV;
-
- /* assumes non-SMP */
- local_irq_save(flags);
- if (mA >= 500)
- mA = 500;
- else if (mA >= 100)
- mA = 100;
- else
- mA = 0;
- the_tps->vbus = mA;
- if ((the_tps->chgstatus & TPS_CHG_USB)
- && test_and_set_bit(
- FLAG_VBUS_CHANGED, &the_tps->flags)) {
- /* gadget drivers call this in_irq() */
- (void) schedule_work(&the_tps->work.work);
- }
- local_irq_restore(flags);
-
- return 0;
-}
-EXPORT_SYMBOL(tps65010_set_vbus_draw);
-
-/*-------------------------------------------------------------------------*/
-/* tps65010_set_gpio_out_value parameter:
- * gpio: GPIO1, GPIO2, GPIO3 or GPIO4
- * value: LOW or HIGH
- */
-int tps65010_set_gpio_out_value(unsigned gpio, unsigned value)
-{
- int status;
- unsigned defgpio;
-
- if (!the_tps)
- return -ENODEV;
- if ((gpio < GPIO1) || (gpio > GPIO4))
- return -EINVAL;
-
- mutex_lock(&the_tps->lock);
-
- defgpio = i2c_smbus_read_byte_data(the_tps->client, TPS_DEFGPIO);
-
- /* Configure GPIO for output */
- defgpio |= 1 << (gpio + 3);
-
- /* Writing 1 forces a logic 0 on that GPIO and vice versa */
- switch (value) {
- case LOW:
- defgpio |= 1 << (gpio - 1); /* set GPIO low by writing 1 */
- break;
- /* case HIGH: */
- default:
- defgpio &= ~(1 << (gpio - 1)); /* set GPIO high by writing 0 */
- break;
- }
-
- status = i2c_smbus_write_byte_data(the_tps->client,
- TPS_DEFGPIO, defgpio);
-
- pr_debug("%s: gpio%dout = %s, defgpio 0x%02x\n", DRIVER_NAME,
- gpio, value ? "high" : "low",
- i2c_smbus_read_byte_data(the_tps->client, TPS_DEFGPIO));
-
- mutex_unlock(&the_tps->lock);
- return status;
-}
-EXPORT_SYMBOL(tps65010_set_gpio_out_value);
-
-/*-------------------------------------------------------------------------*/
-/* tps65010_set_led parameter:
- * led: LED1 or LED2
- * mode: ON, OFF or BLINK
- */
-int tps65010_set_led(unsigned led, unsigned mode)
-{
- int status;
- unsigned led_on, led_per, offs;
-
- if (!the_tps)
- return -ENODEV;
-
- if (led == LED1)
- offs = 0;
- else {
- offs = 2;
- led = LED2;
- }
-
- mutex_lock(&the_tps->lock);
-
- pr_debug("%s: led%i_on 0x%02x\n", DRIVER_NAME, led,
- i2c_smbus_read_byte_data(the_tps->client,
- TPS_LED1_ON + offs));
-
- pr_debug("%s: led%i_per 0x%02x\n", DRIVER_NAME, led,
- i2c_smbus_read_byte_data(the_tps->client,
- TPS_LED1_PER + offs));
-
- switch (mode) {
- case OFF:
- led_on = 1 << 7;
- led_per = 0 << 7;
- break;
- case ON:
- led_on = 1 << 7;
- led_per = 1 << 7;
- break;
- case BLINK:
- led_on = 0x30 | (0 << 7);
- led_per = 0x08 | (1 << 7);
- break;
- default:
- printk(KERN_ERR "%s: Wrong mode parameter for set_led()\n",
- DRIVER_NAME);
- mutex_unlock(&the_tps->lock);
- return -EINVAL;
- }
-
- status = i2c_smbus_write_byte_data(the_tps->client,
- TPS_LED1_ON + offs, led_on);
-
- if (status != 0) {
- printk(KERN_ERR "%s: Failed to write led%i_on register\n",
- DRIVER_NAME, led);
- mutex_unlock(&the_tps->lock);
- return status;
- }
-
- pr_debug("%s: led%i_on 0x%02x\n", DRIVER_NAME, led,
- i2c_smbus_read_byte_data(the_tps->client, TPS_LED1_ON + offs));
-
- status = i2c_smbus_write_byte_data(the_tps->client,
- TPS_LED1_PER + offs, led_per);
-
- if (status != 0) {
- printk(KERN_ERR "%s: Failed to write led%i_per register\n",
- DRIVER_NAME, led);
- mutex_unlock(&the_tps->lock);
- return status;
- }
-
- pr_debug("%s: led%i_per 0x%02x\n", DRIVER_NAME, led,
- i2c_smbus_read_byte_data(the_tps->client,
- TPS_LED1_PER + offs));
-
- mutex_unlock(&the_tps->lock);
-
- return status;
-}
-EXPORT_SYMBOL(tps65010_set_led);
-
-/*-------------------------------------------------------------------------*/
-/* tps65010_set_vib parameter:
- * value: ON or OFF
- */
-int tps65010_set_vib(unsigned value)
-{
- int status;
- unsigned vdcdc2;
-
- if (!the_tps)
- return -ENODEV;
-
- mutex_lock(&the_tps->lock);
-
- vdcdc2 = i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC2);
- vdcdc2 &= ~(1 << 1);
- if (value)
- vdcdc2 |= (1 << 1);
- status = i2c_smbus_write_byte_data(the_tps->client,
- TPS_VDCDC2, vdcdc2);
-
- pr_debug("%s: vibrator %s\n", DRIVER_NAME, value ? "on" : "off");
-
- mutex_unlock(&the_tps->lock);
- return status;
-}
-EXPORT_SYMBOL(tps65010_set_vib);
-
-/*-------------------------------------------------------------------------*/
-/* tps65010_set_low_pwr parameter:
- * mode: ON or OFF
- */
-int tps65010_set_low_pwr(unsigned mode)
-{
- int status;
- unsigned vdcdc1;
-
- if (!the_tps)
- return -ENODEV;
-
- mutex_lock(&the_tps->lock);
-
- pr_debug("%s: %s low_pwr, vdcdc1 0x%02x\n", DRIVER_NAME,
- mode ? "enable" : "disable",
- i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1));
-
- vdcdc1 = i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1);
-
- switch (mode) {
- case OFF:
- vdcdc1 &= ~TPS_ENABLE_LP; /* disable ENABLE_LP bit */
- break;
- /* case ON: */
- default:
- vdcdc1 |= TPS_ENABLE_LP; /* enable ENABLE_LP bit */
- break;
- }
-
- status = i2c_smbus_write_byte_data(the_tps->client,
- TPS_VDCDC1, vdcdc1);
-
- if (status != 0)
- printk(KERN_ERR "%s: Failed to write vdcdc1 register\n",
- DRIVER_NAME);
- else
- pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME,
- i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1));
-
- mutex_unlock(&the_tps->lock);
-
- return status;
-}
-EXPORT_SYMBOL(tps65010_set_low_pwr);
-
-/*-------------------------------------------------------------------------*/
-/* tps65010_config_vregs1 parameter:
- * value to be written to VREGS1 register
- * Note: The complete register is written, set all bits you need
- */
-int tps65010_config_vregs1(unsigned value)
-{
- int status;
-
- if (!the_tps)
- return -ENODEV;
-
- mutex_lock(&the_tps->lock);
-
- pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME,
- i2c_smbus_read_byte_data(the_tps->client, TPS_VREGS1));
-
- status = i2c_smbus_write_byte_data(the_tps->client,
- TPS_VREGS1, value);
-
- if (status != 0)
- printk(KERN_ERR "%s: Failed to write vregs1 register\n",
- DRIVER_NAME);
- else
- pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME,
- i2c_smbus_read_byte_data(the_tps->client, TPS_VREGS1));
-
- mutex_unlock(&the_tps->lock);
-
- return status;
-}
-EXPORT_SYMBOL(tps65010_config_vregs1);
-
-/*-------------------------------------------------------------------------*/
-/* tps65013_set_low_pwr parameter:
- * mode: ON or OFF
- */
-
-/* FIXME: Assumes AC or USB power is present. Setting AUA bit is not
- required if power supply is through a battery */
-
-int tps65013_set_low_pwr(unsigned mode)
-{
- int status;
- unsigned vdcdc1, chgconfig;
-
- if (!the_tps || the_tps->por)
- return -ENODEV;
-
- mutex_lock(&the_tps->lock);
-
- pr_debug("%s: %s low_pwr, chgconfig 0x%02x vdcdc1 0x%02x\n",
- DRIVER_NAME,
- mode ? "enable" : "disable",
- i2c_smbus_read_byte_data(the_tps->client, TPS_CHGCONFIG),
- i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1));
-
- chgconfig = i2c_smbus_read_byte_data(the_tps->client, TPS_CHGCONFIG);
- vdcdc1 = i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1);
-
- switch (mode) {
- case OFF:
- chgconfig &= ~TPS65013_AUA; /* disable AUA bit */
- vdcdc1 &= ~TPS_ENABLE_LP; /* disable ENABLE_LP bit */
- break;
- /* case ON: */
- default:
- chgconfig |= TPS65013_AUA; /* enable AUA bit */
- vdcdc1 |= TPS_ENABLE_LP; /* enable ENABLE_LP bit */
- break;
- }
-
- status = i2c_smbus_write_byte_data(the_tps->client,
- TPS_CHGCONFIG, chgconfig);
- if (status != 0) {
- printk(KERN_ERR "%s: Failed to write chconfig register\n",
- DRIVER_NAME);
- mutex_unlock(&the_tps->lock);
- return status;
- }
-
- chgconfig = i2c_smbus_read_byte_data(the_tps->client, TPS_CHGCONFIG);
- the_tps->chgconf = chgconfig;
- show_chgconfig(0, "chgconf", chgconfig);
-
- status = i2c_smbus_write_byte_data(the_tps->client,
- TPS_VDCDC1, vdcdc1);
-
- if (status != 0)
- printk(KERN_ERR "%s: Failed to write vdcdc1 register\n",
- DRIVER_NAME);
- else
- pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME,
- i2c_smbus_read_byte_data(the_tps->client, TPS_VDCDC1));
-
- mutex_unlock(&the_tps->lock);
-
- return status;
-}
-EXPORT_SYMBOL(tps65013_set_low_pwr);
-
-/*-------------------------------------------------------------------------*/
-
-static int __init tps_init(void)
-{
- u32 tries = 3;
- int status = -ENODEV;
-
- printk(KERN_INFO "%s: version %s\n", DRIVER_NAME, DRIVER_VERSION);
-
- /* some boards have startup glitches */
- while (tries--) {
- status = i2c_add_driver(&tps65010_driver);
- if (the_tps)
- break;
- i2c_del_driver(&tps65010_driver);
- if (!tries) {
- printk(KERN_ERR "%s: no chip?\n", DRIVER_NAME);
- return -ENODEV;
- }
- pr_debug("%s: re-probe ...\n", DRIVER_NAME);
- msleep(10);
- }
-
- return status;
-}
-/* NOTE: this MUST be initialized before the other parts of the system
- * that rely on it ... but after the i2c bus on which this relies.
- * That is, much earlier than on PC-type systems, which don't often use
- * I2C as a core system bus.
- */
-subsys_initcall(tps_init);
-
-static void __exit tps_exit(void)
-{
- i2c_del_driver(&tps65010_driver);
-}
-module_exit(tps_exit);
-
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
deleted file mode 100644
index a10fd2791a6..00000000000
--- a/drivers/i2c/chips/tsl2550.c
+++ /dev/null
@@ -1,481 +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)
-{
- 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 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),
-};
-
-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);