[PATCH v2 02/09] mfd: support 88pm8606 in 860x driver
Samuel Ortiz
sameo at linux.intel.com
Thu Jan 7 14:44:04 EST 2010
Hi Haojian,
On Wed, Dec 09, 2009 at 08:11:22AM -0500, Haojian Zhuang wrote:
> From c5f9ccd5b1f2ce57b9e10b7e2b6c134fc8116f29 Mon Sep 17 00:00:00 2001
> From: Haojian Zhuang <haojian.zhuang at marvell.com>
> Date: Tue, 8 Dec 2009 09:05:28 -0500
> Subject: [PATCH] mfd: support 88pm8606 in 860x driver
>
> 88PM8606 and 88PM8607 are two discrete chips used for power management.
> Hardware designer can use them together or only one of them according to
> requirement.
>
> There's some logic tightly linked between these two chips. For example, USB
> charger driver needs to access both chips by I2C interface.
>
> Now share one driver to these two devices. Only one I2C client is identified
> in platform init data. If another chip is also used, user should mark it in
> companion_addr field of platform init data. Then driver could create another
> I2C client for the companion chip.
>
> All I2C operations are accessed by 860x-i2c driver. In order to support both
> I2C client address, the read/write API is changed in below.
>
> reg_read(client, offset)
> reg_write(client, offset, data)
>
> The benefit is that client drivers only need one kind of read/write API. I2C
> and MFD driver can be shared in both 8606 and 8607.
After merging this patch, I get many drivers/regulator/88pm8607.c build
failures. Could you please include fixes for this driver with this patch, and
also update patch #9 accordingly ?
Cheers,
Samuel.
> Signed-off-by: Haojian Zhuang <haojian.zhuang at marvell.com>
> ---
> drivers/mfd/88pm860x-core.c | 61 ++++++++----
> drivers/mfd/88pm860x-i2c.c | 156 +++++++++++++++++++----------
> include/linux/mfd/88pm8607.h | 223 -----------------------------------------
> include/linux/mfd/88pm860x.h | 226 ++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 369 insertions(+), 297 deletions(-)
> delete mode 100644 include/linux/mfd/88pm8607.h
> create mode 100644 include/linux/mfd/88pm860x.h
>
> diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
> index d1464e5..72b0030 100644
> --- a/drivers/mfd/88pm860x-core.c
> +++ b/drivers/mfd/88pm860x-core.c
> @@ -14,7 +14,7 @@
> #include <linux/interrupt.h>
> #include <linux/platform_device.h>
> #include <linux/mfd/core.h>
> -#include <linux/mfd/88pm8607.h>
> +#include <linux/mfd/88pm860x.h>
>
>
> #define PM8607_REG_RESOURCE(_start, _end) \
> @@ -67,18 +67,23 @@ static struct mfd_cell pm8607_devs[] = {
> PM8607_REG_DEVS(ldo14, LDO14),
> };
>
> -int pm860x_device_init(struct pm8607_chip *chip,
> - struct pm8607_platform_data *pdata)
> +static void device_8606_init(struct pm860x_chip *chip, struct i2c_client *i2c,
> + struct pm860x_platform_data *pdata)
> +{
> +}
> +
> +static void device_8607_init(struct pm860x_chip *chip, struct i2c_client *i2c,
> + struct pm860x_platform_data *pdata)
> {
> int i, count;
> int ret;
>
> - ret = pm8607_reg_read(chip, PM8607_CHIP_ID);
> + ret = pm860x_reg_read(i2c, PM8607_CHIP_ID);
> if (ret < 0) {
> dev_err(chip->dev, "Failed to read CHIP ID: %d\n", ret);
> goto out;
> }
> - if ((ret & PM8607_ID_MASK) == PM8607_ID)
> + if ((ret & PM8607_VERSION_MASK) == PM8607_VERSION)
> dev_info(chip->dev, "Marvell 88PM8607 (ID: %02x) detected\n",
> ret);
> else {
> @@ -86,9 +91,9 @@ int pm860x_device_init(struct pm8607_chip *chip,
> "Chip ID: %02x\n", ret);
> goto out;
> }
> - chip->chip_id = ret;
> + chip->chip_version = ret;
>
> - ret = pm8607_reg_read(chip, PM8607_BUCK3);
> + ret = pm860x_reg_read(i2c, PM8607_BUCK3);
> if (ret < 0) {
> dev_err(chip->dev, "Failed to read BUCK3 register: %d\n", ret);
> goto out;
> @@ -96,20 +101,11 @@ int pm860x_device_init(struct pm8607_chip *chip,
> if (ret & PM8607_BUCK3_DOUBLE)
> chip->buck3_double = 1;
>
> - ret = pm8607_reg_read(chip, PM8607_MISC1);
> + ret = pm860x_reg_read(i2c, PM8607_MISC1);
> if (ret < 0) {
> dev_err(chip->dev, "Failed to read MISC1 register: %d\n", ret);
> goto out;
> }
> - if (pdata->i2c_port == PI2C_PORT)
> - ret |= PM8607_MISC1_PI2C;
> - else
> - ret &= ~PM8607_MISC1_PI2C;
> - ret = pm8607_reg_write(chip, PM8607_MISC1, ret);
> - if (ret < 0) {
> - dev_err(chip->dev, "Failed to write MISC1 register: %d\n", ret);
> - goto out;
> - }
>
> count = ARRAY_SIZE(pm8607_devs);
> for (i = 0; i < count; i++) {
> @@ -121,14 +117,39 @@ int pm860x_device_init(struct pm8607_chip *chip,
> }
> }
> out:
> - return ret;
> + return;
> +}
> +
> +int pm860x_device_init(struct pm860x_chip *chip,
> + struct pm860x_platform_data *pdata)
> +{
> + switch (chip->id) {
> + case CHIP_PM8606:
> + device_8606_init(chip, chip->client, pdata);
> + break;
> + case CHIP_PM8607:
> + device_8607_init(chip, chip->client, pdata);
> + break;
> + }
> +
> + if (chip->companion) {
> + switch (chip->id) {
> + case CHIP_PM8607:
> + device_8606_init(chip, chip->companion, pdata);
> + break;
> + case CHIP_PM8606:
> + device_8607_init(chip, chip->companion, pdata);
> + break;
> + }
> + }
> + return 0;
> }
>
> -void pm8607_device_exit(struct pm8607_chip *chip)
> +void pm860x_device_exit(struct pm860x_chip *chip)
> {
> mfd_remove_devices(chip->dev);
> }
>
> -MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM8607");
> +MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
> MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang at marvell.com>");
> MODULE_LICENSE("GPL");
> diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
> index dda23cb..a5c6b49 100644
> --- a/drivers/mfd/88pm860x-i2c.c
> +++ b/drivers/mfd/88pm860x-i2c.c
> @@ -1,5 +1,5 @@
> /*
> - * I2C driver for Marvell 88PM8607
> + * I2C driver for Marvell 88PM860x
> *
> * Copyright (C) 2009 Marvell International Ltd.
> * Haojian Zhuang <haojian.zhuang at marvell.com>
> @@ -12,12 +12,13 @@
> #include <linux/module.h>
> #include <linux/platform_device.h>
> #include <linux/i2c.h>
> -#include <linux/mfd/88pm8607.h>
> +#include <linux/mfd/88pm860x.h>
>
> -static inline int pm8607_read_device(struct pm8607_chip *chip,
> +static struct mutex io_lock;
> +
> +static inline int pm860x_read_device(struct i2c_client *i2c,
> int reg, int bytes, void *dest)
> {
> - struct i2c_client *i2c = chip->client;
> unsigned char data;
> int ret;
>
> @@ -32,10 +33,9 @@ static inline int pm8607_read_device(struct
> pm8607_chip *chip,
> return 0;
> }
>
> -static inline int pm8607_write_device(struct pm8607_chip *chip,
> +static inline int pm860x_write_device(struct i2c_client *i2c,
> int reg, int bytes, void *src)
> {
> - struct i2c_client *i2c = chip->client;
> unsigned char buf[bytes + 1];
> int ret;
>
> @@ -48,116 +48,162 @@ static inline int pm8607_write_device(struct
> pm8607_chip *chip,
> return 0;
> }
>
> -int pm8607_reg_read(struct pm8607_chip *chip, int reg)
> +int pm860x_reg_read(struct i2c_client *i2c, int reg)
> {
> unsigned char data;
> int ret;
>
> - mutex_lock(&chip->io_lock);
> - ret = chip->read(chip, reg, 1, &data);
> - mutex_unlock(&chip->io_lock);
> + mutex_lock(&io_lock);
> + ret = pm860x_read_device(i2c, reg, 1, &data);
> + mutex_unlock(&io_lock);
>
> if (ret < 0)
> return ret;
> else
> return (int)data;
> }
> -EXPORT_SYMBOL(pm8607_reg_read);
> +EXPORT_SYMBOL(pm860x_reg_read);
>
> -int pm8607_reg_write(struct pm8607_chip *chip, int reg,
> +int pm860x_reg_write(struct i2c_client *i2c, int reg,
> unsigned char data)
> {
> int ret;
>
> - mutex_lock(&chip->io_lock);
> - ret = chip->write(chip, reg, 1, &data);
> - mutex_unlock(&chip->io_lock);
> + mutex_lock(&io_lock);
> + ret = pm860x_write_device(i2c, reg, 1, &data);
> + mutex_unlock(&io_lock);
>
> return ret;
> }
> -EXPORT_SYMBOL(pm8607_reg_write);
> +EXPORT_SYMBOL(pm860x_reg_write);
>
> -int pm8607_bulk_read(struct pm8607_chip *chip, int reg,
> +int pm860x_bulk_read(struct i2c_client *i2c, int reg,
> int count, unsigned char *buf)
> {
> int ret;
>
> - mutex_lock(&chip->io_lock);
> - ret = chip->read(chip, reg, count, buf);
> - mutex_unlock(&chip->io_lock);
> + mutex_lock(&io_lock);
> + ret = pm860x_read_device(i2c, reg, count, buf);
> + mutex_unlock(&io_lock);
>
> return ret;
> }
> -EXPORT_SYMBOL(pm8607_bulk_read);
> +EXPORT_SYMBOL(pm860x_bulk_read);
>
> -int pm8607_bulk_write(struct pm8607_chip *chip, int reg,
> +int pm860x_bulk_write(struct i2c_client *i2c, int reg,
> int count, unsigned char *buf)
> {
> int ret;
>
> - mutex_lock(&chip->io_lock);
> - ret = chip->write(chip, reg, count, buf);
> - mutex_unlock(&chip->io_lock);
> + mutex_lock(&io_lock);
> + ret = pm860x_write_device(i2c, reg, count, buf);
> + mutex_unlock(&io_lock);
>
> return ret;
> }
> -EXPORT_SYMBOL(pm8607_bulk_write);
> +EXPORT_SYMBOL(pm860x_bulk_write);
>
> -int pm8607_set_bits(struct pm8607_chip *chip, int reg,
> +int pm860x_set_bits(struct i2c_client *i2c, int reg,
> unsigned char mask, unsigned char data)
> {
> unsigned char value;
> int ret;
>
> - mutex_lock(&chip->io_lock);
> - ret = chip->read(chip, reg, 1, &value);
> + mutex_lock(&io_lock);
> + ret = pm860x_read_device(i2c, reg, 1, &value);
> if (ret < 0)
> goto out;
> value &= ~mask;
> value |= data;
> - ret = chip->write(chip, reg, 1, &value);
> + ret = pm860x_write_device(i2c, reg, 1, &value);
> out:
> - mutex_unlock(&chip->io_lock);
> + mutex_unlock(&io_lock);
> return ret;
> }
> -EXPORT_SYMBOL(pm8607_set_bits);
> +EXPORT_SYMBOL(pm860x_set_bits);
>
>
> static const struct i2c_device_id pm860x_id_table[] = {
> - { "88PM8607", 0 },
> + { "88PM860x", 0 },
> {}
> };
> MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
>
> +static int verify_addr(struct i2c_client *i2c)
> +{
> + unsigned short addr_8607[] = {0x30, 0x34};
> + unsigned short addr_8606[] = {0x10, 0x11};
> + int size, i;
> +
> + if (i2c == NULL)
> + return 0;
> + size = ARRAY_SIZE(addr_8606);
> + for (i = 0; i < size; i++) {
> + if (i2c->addr == *(addr_8606 + i))
> + return CHIP_PM8606;
> + }
> + size = ARRAY_SIZE(addr_8607);
> + for (i = 0; i < size; i++) {
> + if (i2c->addr == *(addr_8607 + i))
> + return CHIP_PM8607;
> + }
> + return 0;
> +}
> +
> static int __devinit pm860x_probe(struct i2c_client *client,
> const struct i2c_device_id *id)
> {
> - struct pm8607_platform_data *pdata = client->dev.platform_data;
> - struct pm8607_chip *chip;
> + struct pm860x_platform_data *pdata = client->dev.platform_data;
> + struct pm860x_chip *chip;
> + struct i2c_board_info i2c_info = {
> + .type = "88PM860x",
> + .platform_data = client->dev.platform_data,
> + };
> + int addr_c, found_companion = 0;
> int ret;
>
> - chip = kzalloc(sizeof(struct pm8607_chip), GFP_KERNEL);
> - if (chip == NULL)
> - return -ENOMEM;
> -
> - chip->client = client;
> - chip->dev = &client->dev;
> - chip->read = pm8607_read_device;
> - chip->write = pm8607_write_device;
> - memcpy(&chip->id, id, sizeof(struct i2c_device_id));
> - i2c_set_clientdata(client, chip);
> -
> - mutex_init(&chip->io_lock);
> - dev_set_drvdata(chip->dev, chip);
> -
> - ret = pm860x_device_init(chip, pdata);
> - if (ret < 0)
> - goto out;
> -
> + if (pdata == NULL) {
> + pr_info("No platform data in %s!\n", __func__);
> + return -EINVAL;
> + }
> +
> + addr_c = pdata->companion_addr;
> + if (addr_c && (addr_c != client->addr)) {
> + i2c_info.addr = addr_c;
> + found_companion = 1;
> + }
> +
> + if (found_companion || (addr_c == 0)) {
> + chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
> + if (chip == NULL)
> + return -ENOMEM;
> +
> + chip->id = verify_addr(client);
> + chip->client = client;
> + i2c_set_clientdata(client, chip);
> + chip->dev = &client->dev;
> + mutex_init(&io_lock);
> + dev_set_drvdata(chip->dev, chip);
> +
> + if (found_companion) {
> + chip->companion = i2c_new_device(client->adapter,
> + &i2c_info);
> + i2c_set_clientdata(chip->companion, chip);
> + }
> +
> + ret = pm860x_device_init(chip, pdata);
> + if (ret < 0)
> + goto out;
> + }
>
> return 0;
>
> out:
> + if (chip->companion) {
> + i2c_unregister_device(chip->companion);
> + i2c_set_clientdata(chip->companion, NULL);
> + return 0;
> + }
> i2c_set_clientdata(client, NULL);
> kfree(chip);
> return ret;
> @@ -165,8 +211,10 @@ out:
>
> static int __devexit pm860x_remove(struct i2c_client *client)
> {
> - struct pm8607_chip *chip = i2c_get_clientdata(client);
> + struct pm860x_chip *chip = i2c_get_clientdata(client);
>
> + if (chip->companion)
> + i2c_unregister_device(chip->companion);
> kfree(chip);
> return 0;
> }
> diff --git a/include/linux/mfd/88pm8607.h b/include/linux/mfd/88pm8607.h
> deleted file mode 100644
> index 6e4dcdc..0000000
> --- a/include/linux/mfd/88pm8607.h
> +++ /dev/null
> @@ -1,223 +0,0 @@
> -/*
> - * Marvell 88PM8607 Interface
> - *
> - * Copyright (C) 2009 Marvell International Ltd.
> - * Haojian Zhuang <haojian.zhuang at marvell.com>
> - *
> - * 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.
> - */
> -
> -#ifndef __LINUX_MFD_88PM8607_H
> -#define __LINUX_MFD_88PM8607_H
> -
> -enum {
> - PM8607_ID_BUCK1 = 0,
> - PM8607_ID_BUCK2,
> - PM8607_ID_BUCK3,
> -
> - PM8607_ID_LDO1,
> - PM8607_ID_LDO2,
> - PM8607_ID_LDO3,
> - PM8607_ID_LDO4,
> - PM8607_ID_LDO5,
> - PM8607_ID_LDO6,
> - PM8607_ID_LDO7,
> - PM8607_ID_LDO8,
> - PM8607_ID_LDO9,
> - PM8607_ID_LDO10,
> - PM8607_ID_LDO12,
> - PM8607_ID_LDO14,
> -
> - PM8607_ID_RG_MAX,
> -};
> -
> -#define PM8607_ID (0x40) /* 8607 chip ID */
> -#define PM8607_ID_MASK (0xF8) /* 8607 chip ID mask */
> -
> -/* Interrupt Registers */
> -#define PM8607_STATUS_1 (0x01)
> -#define PM8607_STATUS_2 (0x02)
> -#define PM8607_INT_STATUS1 (0x03)
> -#define PM8607_INT_STATUS2 (0x04)
> -#define PM8607_INT_STATUS3 (0x05)
> -#define PM8607_INT_MASK_1 (0x06)
> -#define PM8607_INT_MASK_2 (0x07)
> -#define PM8607_INT_MASK_3 (0x08)
> -
> -/* Regulator Control Registers */
> -#define PM8607_LDO1 (0x10)
> -#define PM8607_LDO2 (0x11)
> -#define PM8607_LDO3 (0x12)
> -#define PM8607_LDO4 (0x13)
> -#define PM8607_LDO5 (0x14)
> -#define PM8607_LDO6 (0x15)
> -#define PM8607_LDO7 (0x16)
> -#define PM8607_LDO8 (0x17)
> -#define PM8607_LDO9 (0x18)
> -#define PM8607_LDO10 (0x19)
> -#define PM8607_LDO12 (0x1A)
> -#define PM8607_LDO14 (0x1B)
> -#define PM8607_SLEEP_MODE1 (0x1C)
> -#define PM8607_SLEEP_MODE2 (0x1D)
> -#define PM8607_SLEEP_MODE3 (0x1E)
> -#define PM8607_SLEEP_MODE4 (0x1F)
> -#define PM8607_GO (0x20)
> -#define PM8607_SLEEP_BUCK1 (0x21)
> -#define PM8607_SLEEP_BUCK2 (0x22)
> -#define PM8607_SLEEP_BUCK3 (0x23)
> -#define PM8607_BUCK1 (0x24)
> -#define PM8607_BUCK2 (0x25)
> -#define PM8607_BUCK3 (0x26)
> -#define PM8607_BUCK_CONTROLS (0x27)
> -#define PM8607_SUPPLIES_EN11 (0x2B)
> -#define PM8607_SUPPLIES_EN12 (0x2C)
> -#define PM8607_GROUP1 (0x2D)
> -#define PM8607_GROUP2 (0x2E)
> -#define PM8607_GROUP3 (0x2F)
> -#define PM8607_GROUP4 (0x30)
> -#define PM8607_GROUP5 (0x31)
> -#define PM8607_GROUP6 (0x32)
> -#define PM8607_SUPPLIES_EN21 (0x33)
> -#define PM8607_SUPPLIES_EN22 (0x34)
> -
> -/* RTC Control Registers */
> -#define PM8607_RTC1 (0xA0)
> -#define PM8607_RTC_COUNTER1 (0xA1)
> -#define PM8607_RTC_COUNTER2 (0xA2)
> -#define PM8607_RTC_COUNTER3 (0xA3)
> -#define PM8607_RTC_COUNTER4 (0xA4)
> -#define PM8607_RTC_EXPIRE1 (0xA5)
> -#define PM8607_RTC_EXPIRE2 (0xA6)
> -#define PM8607_RTC_EXPIRE3 (0xA7)
> -#define PM8607_RTC_EXPIRE4 (0xA8)
> -#define PM8607_RTC_TRIM1 (0xA9)
> -#define PM8607_RTC_TRIM2 (0xAA)
> -#define PM8607_RTC_TRIM3 (0xAB)
> -#define PM8607_RTC_TRIM4 (0xAC)
> -#define PM8607_RTC_MISC1 (0xAD)
> -#define PM8607_RTC_MISC2 (0xAE)
> -#define PM8607_RTC_MISC3 (0xAF)
> -
> -/* Misc Registers */
> -#define PM8607_CHIP_ID (0x00)
> -#define PM8607_LDO1 (0x10)
> -#define PM8607_DVC3 (0x26)
> -#define PM8607_MISC1 (0x40)
> -
> -/* bit definitions for PM8607 events */
> -#define PM8607_EVENT_ONKEY (1 << 0)
> -#define PM8607_EVENT_EXTON (1 << 1)
> -#define PM8607_EVENT_CHG (1 << 2)
> -#define PM8607_EVENT_BAT (1 << 3)
> -#define PM8607_EVENT_RTC (1 << 4)
> -#define PM8607_EVENT_CC (1 << 5)
> -#define PM8607_EVENT_VBAT (1 << 8)
> -#define PM8607_EVENT_VCHG (1 << 9)
> -#define PM8607_EVENT_VSYS (1 << 10)
> -#define PM8607_EVENT_TINT (1 << 11)
> -#define PM8607_EVENT_GPADC0 (1 << 12)
> -#define PM8607_EVENT_GPADC1 (1 << 13)
> -#define PM8607_EVENT_GPADC2 (1 << 14)
> -#define PM8607_EVENT_GPADC3 (1 << 15)
> -#define PM8607_EVENT_AUDIO_SHORT (1 << 16)
> -#define PM8607_EVENT_PEN (1 << 17)
> -#define PM8607_EVENT_HEADSET (1 << 18)
> -#define PM8607_EVENT_HOOK (1 << 19)
> -#define PM8607_EVENT_MICIN (1 << 20)
> -#define PM8607_EVENT_CHG_TIMEOUT (1 << 21)
> -#define PM8607_EVENT_CHG_DONE (1 << 22)
> -#define PM8607_EVENT_CHG_FAULT (1 << 23)
> -
> -/* bit definitions of Status Query Interface */
> -#define PM8607_STATUS_CC (1 << 3)
> -#define PM8607_STATUS_PEN (1 << 4)
> -#define PM8607_STATUS_HEADSET (1 << 5)
> -#define PM8607_STATUS_HOOK (1 << 6)
> -#define PM8607_STATUS_MICIN (1 << 7)
> -#define PM8607_STATUS_ONKEY (1 << 8)
> -#define PM8607_STATUS_EXTON (1 << 9)
> -#define PM8607_STATUS_CHG (1 << 10)
> -#define PM8607_STATUS_BAT (1 << 11)
> -#define PM8607_STATUS_VBUS (1 << 12)
> -#define PM8607_STATUS_OV (1 << 13)
> -
> -/* bit definitions of BUCK3 */
> -#define PM8607_BUCK3_DOUBLE (1 << 6)
> -
> -/* bit definitions of Misc1 */
> -#define PM8607_MISC1_PI2C (1 << 0)
> -
> -/* Interrupt Number in 88PM8607 */
> -enum {
> - PM8607_IRQ_ONKEY = 0,
> - PM8607_IRQ_EXTON,
> - PM8607_IRQ_CHG,
> - PM8607_IRQ_BAT,
> - PM8607_IRQ_RTC,
> - PM8607_IRQ_VBAT = 8,
> - PM8607_IRQ_VCHG,
> - PM8607_IRQ_VSYS,
> - PM8607_IRQ_TINT,
> - PM8607_IRQ_GPADC0,
> - PM8607_IRQ_GPADC1,
> - PM8607_IRQ_GPADC2,
> - PM8607_IRQ_GPADC3,
> - PM8607_IRQ_AUDIO_SHORT = 16,
> - PM8607_IRQ_PEN,
> - PM8607_IRQ_HEADSET,
> - PM8607_IRQ_HOOK,
> - PM8607_IRQ_MICIN,
> - PM8607_IRQ_CHG_FAIL,
> - PM8607_IRQ_CHG_DONE,
> - PM8607_IRQ_CHG_FAULT,
> -};
> -
> -enum {
> - PM8607_CHIP_A0 = 0x40,
> - PM8607_CHIP_A1 = 0x41,
> - PM8607_CHIP_B0 = 0x48,
> -};
> -
> -
> -struct pm8607_chip {
> - struct device *dev;
> - struct mutex io_lock;
> - struct i2c_client *client;
> - struct i2c_device_id id;
> -
> - int (*read)(struct pm8607_chip *chip, int reg, int bytes, void *dest);
> - int (*write)(struct pm8607_chip *chip, int reg, int bytes, void *src);
> -
> - int buck3_double; /* DVC ramp slope double */
> - unsigned char chip_id;
> -
> -};
> -
> -#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */
> -
> -enum {
> - GI2C_PORT = 0,
> - PI2C_PORT,
> -};
> -
> -struct pm8607_platform_data {
> - int i2c_port; /* Controlled by GI2C or PI2C */
> - struct regulator_init_data *regulator[PM8607_MAX_REGULATOR];
> -};
> -
> -extern int pm8607_reg_read(struct pm8607_chip *, int);
> -extern int pm8607_reg_write(struct pm8607_chip *, int, unsigned char);
> -extern int pm8607_bulk_read(struct pm8607_chip *, int, int,
> - unsigned char *);
> -extern int pm8607_bulk_write(struct pm8607_chip *, int, int,
> - unsigned char *);
> -extern int pm8607_set_bits(struct pm8607_chip *, int, unsigned char,
> - unsigned char);
> -
> -extern int pm860x_device_init(struct pm8607_chip *chip,
> - struct pm8607_platform_data *pdata);
> -extern void pm860x_device_exit(struct pm8607_chip *chip);
> -
> -#endif /* __LINUX_MFD_88PM860X_H */
> diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
> new file mode 100644
> index 0000000..b648b9f
> --- /dev/null
> +++ b/include/linux/mfd/88pm860x.h
> @@ -0,0 +1,226 @@
> +/*
> + * Marvell 88PM860x Interface
> + *
> + * Copyright (C) 2009 Marvell International Ltd.
> + * Haojian Zhuang <haojian.zhuang at marvell.com>
> + *
> + * 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.
> + */
> +
> +#ifndef __LINUX_MFD_88PM860X_H
> +#define __LINUX_MFD_88PM860X_H
> +
> +enum {
> + CHIP_INVALID = 0,
> + CHIP_PM8606,
> + CHIP_PM8607,
> + CHIP_MAX,
> +};
> +
> +enum {
> + PM8607_ID_BUCK1 = 0,
> + PM8607_ID_BUCK2,
> + PM8607_ID_BUCK3,
> +
> + PM8607_ID_LDO1,
> + PM8607_ID_LDO2,
> + PM8607_ID_LDO3,
> + PM8607_ID_LDO4,
> + PM8607_ID_LDO5,
> + PM8607_ID_LDO6,
> + PM8607_ID_LDO7,
> + PM8607_ID_LDO8,
> + PM8607_ID_LDO9,
> + PM8607_ID_LDO10,
> + PM8607_ID_LDO12,
> + PM8607_ID_LDO14,
> +
> + PM8607_ID_RG_MAX,
> +};
> +
> +#define PM8607_VERSION (0x40) /* 8607 chip ID */
> +#define PM8607_VERSION_MASK (0xF0) /* 8607 chip ID mask */
> +
> +/* Interrupt Registers */
> +#define PM8607_STATUS_1 (0x01)
> +#define PM8607_STATUS_2 (0x02)
> +#define PM8607_INT_STATUS1 (0x03)
> +#define PM8607_INT_STATUS2 (0x04)
> +#define PM8607_INT_STATUS3 (0x05)
> +#define PM8607_INT_MASK_1 (0x06)
> +#define PM8607_INT_MASK_2 (0x07)
> +#define PM8607_INT_MASK_3 (0x08)
> +
> +/* Regulator Control Registers */
> +#define PM8607_LDO1 (0x10)
> +#define PM8607_LDO2 (0x11)
> +#define PM8607_LDO3 (0x12)
> +#define PM8607_LDO4 (0x13)
> +#define PM8607_LDO5 (0x14)
> +#define PM8607_LDO6 (0x15)
> +#define PM8607_LDO7 (0x16)
> +#define PM8607_LDO8 (0x17)
> +#define PM8607_LDO9 (0x18)
> +#define PM8607_LDO10 (0x19)
> +#define PM8607_LDO12 (0x1A)
> +#define PM8607_LDO14 (0x1B)
> +#define PM8607_SLEEP_MODE1 (0x1C)
> +#define PM8607_SLEEP_MODE2 (0x1D)
> +#define PM8607_SLEEP_MODE3 (0x1E)
> +#define PM8607_SLEEP_MODE4 (0x1F)
> +#define PM8607_GO (0x20)
> +#define PM8607_SLEEP_BUCK1 (0x21)
> +#define PM8607_SLEEP_BUCK2 (0x22)
> +#define PM8607_SLEEP_BUCK3 (0x23)
> +#define PM8607_BUCK1 (0x24)
> +#define PM8607_BUCK2 (0x25)
> +#define PM8607_BUCK3 (0x26)
> +#define PM8607_BUCK_CONTROLS (0x27)
> +#define PM8607_SUPPLIES_EN11 (0x2B)
> +#define PM8607_SUPPLIES_EN12 (0x2C)
> +#define PM8607_GROUP1 (0x2D)
> +#define PM8607_GROUP2 (0x2E)
> +#define PM8607_GROUP3 (0x2F)
> +#define PM8607_GROUP4 (0x30)
> +#define PM8607_GROUP5 (0x31)
> +#define PM8607_GROUP6 (0x32)
> +#define PM8607_SUPPLIES_EN21 (0x33)
> +#define PM8607_SUPPLIES_EN22 (0x34)
> +
> +/* RTC Control Registers */
> +#define PM8607_RTC1 (0xA0)
> +#define PM8607_RTC_COUNTER1 (0xA1)
> +#define PM8607_RTC_COUNTER2 (0xA2)
> +#define PM8607_RTC_COUNTER3 (0xA3)
> +#define PM8607_RTC_COUNTER4 (0xA4)
> +#define PM8607_RTC_EXPIRE1 (0xA5)
> +#define PM8607_RTC_EXPIRE2 (0xA6)
> +#define PM8607_RTC_EXPIRE3 (0xA7)
> +#define PM8607_RTC_EXPIRE4 (0xA8)
> +#define PM8607_RTC_TRIM1 (0xA9)
> +#define PM8607_RTC_TRIM2 (0xAA)
> +#define PM8607_RTC_TRIM3 (0xAB)
> +#define PM8607_RTC_TRIM4 (0xAC)
> +#define PM8607_RTC_MISC1 (0xAD)
> +#define PM8607_RTC_MISC2 (0xAE)
> +#define PM8607_RTC_MISC3 (0xAF)
> +
> +/* Misc Registers */
> +#define PM8607_CHIP_ID (0x00)
> +#define PM8607_LDO1 (0x10)
> +#define PM8607_DVC3 (0x26)
> +#define PM8607_MISC1 (0x40)
> +
> +/* bit definitions for PM8607 events */
> +#define PM8607_EVENT_ONKEY (1 << 0)
> +#define PM8607_EVENT_EXTON (1 << 1)
> +#define PM8607_EVENT_CHG (1 << 2)
> +#define PM8607_EVENT_BAT (1 << 3)
> +#define PM8607_EVENT_RTC (1 << 4)
> +#define PM8607_EVENT_CC (1 << 5)
> +#define PM8607_EVENT_VBAT (1 << 8)
> +#define PM8607_EVENT_VCHG (1 << 9)
> +#define PM8607_EVENT_VSYS (1 << 10)
> +#define PM8607_EVENT_TINT (1 << 11)
> +#define PM8607_EVENT_GPADC0 (1 << 12)
> +#define PM8607_EVENT_GPADC1 (1 << 13)
> +#define PM8607_EVENT_GPADC2 (1 << 14)
> +#define PM8607_EVENT_GPADC3 (1 << 15)
> +#define PM8607_EVENT_AUDIO_SHORT (1 << 16)
> +#define PM8607_EVENT_PEN (1 << 17)
> +#define PM8607_EVENT_HEADSET (1 << 18)
> +#define PM8607_EVENT_HOOK (1 << 19)
> +#define PM8607_EVENT_MICIN (1 << 20)
> +#define PM8607_EVENT_CHG_TIMEOUT (1 << 21)
> +#define PM8607_EVENT_CHG_DONE (1 << 22)
> +#define PM8607_EVENT_CHG_FAULT (1 << 23)
> +
> +/* bit definitions of Status Query Interface */
> +#define PM8607_STATUS_CC (1 << 3)
> +#define PM8607_STATUS_PEN (1 << 4)
> +#define PM8607_STATUS_HEADSET (1 << 5)
> +#define PM8607_STATUS_HOOK (1 << 6)
> +#define PM8607_STATUS_MICIN (1 << 7)
> +#define PM8607_STATUS_ONKEY (1 << 8)
> +#define PM8607_STATUS_EXTON (1 << 9)
> +#define PM8607_STATUS_CHG (1 << 10)
> +#define PM8607_STATUS_BAT (1 << 11)
> +#define PM8607_STATUS_VBUS (1 << 12)
> +#define PM8607_STATUS_OV (1 << 13)
> +
> +/* bit definitions of BUCK3 */
> +#define PM8607_BUCK3_DOUBLE (1 << 6)
> +
> +/* bit definitions of Misc1 */
> +#define PM8607_MISC1_PI2C (1 << 0)
> +
> +/* Interrupt Number in 88PM8607 */
> +enum {
> + PM8607_IRQ_ONKEY = 0,
> + PM8607_IRQ_EXTON,
> + PM8607_IRQ_CHG,
> + PM8607_IRQ_BAT,
> + PM8607_IRQ_RTC,
> + PM8607_IRQ_VBAT = 8,
> + PM8607_IRQ_VCHG,
> + PM8607_IRQ_VSYS,
> + PM8607_IRQ_TINT,
> + PM8607_IRQ_GPADC0,
> + PM8607_IRQ_GPADC1,
> + PM8607_IRQ_GPADC2,
> + PM8607_IRQ_GPADC3,
> + PM8607_IRQ_AUDIO_SHORT = 16,
> + PM8607_IRQ_PEN,
> + PM8607_IRQ_HEADSET,
> + PM8607_IRQ_HOOK,
> + PM8607_IRQ_MICIN,
> + PM8607_IRQ_CHG_FAIL,
> + PM8607_IRQ_CHG_DONE,
> + PM8607_IRQ_CHG_FAULT,
> +};
> +
> +enum {
> + PM8607_CHIP_A0 = 0x40,
> + PM8607_CHIP_A1 = 0x41,
> + PM8607_CHIP_B0 = 0x48,
> +};
> +
> +struct pm860x_chip {
> + struct device *dev;
> + struct mutex io_lock;
> + struct i2c_client *client;
> + struct i2c_client *companion; /* companion chip client */
> +
> + int buck3_double; /* DVC ramp slope double */
> + int id;
> + unsigned char chip_version;
> +
> +};
> +
> +#define PM8607_MAX_REGULATOR 15 /* 3 Bucks, 12 LDOs */
> +
> +enum {
> + GI2C_PORT = 0,
> + PI2C_PORT,
> +};
> +
> +struct pm860x_platform_data {
> + unsigned short companion_addr; /* I2C address of companion chip */
> + int i2c_port; /* Controlled by GI2C or PI2C */
> + struct regulator_init_data *regulator[PM8607_MAX_REGULATOR];
> +};
> +
> +extern int pm860x_reg_read(struct i2c_client *, int);
> +extern int pm860x_reg_write(struct i2c_client *, int, unsigned char);
> +extern int pm860x_bulk_read(struct i2c_client *, int, int, unsigned char *);
> +extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *);
> +extern int pm860x_set_bits(struct i2c_client *, int, unsigned char,
> + unsigned char);
> +
> +extern int pm860x_device_init(struct pm860x_chip *chip,
> + struct pm860x_platform_data *pdata);
> +extern void pm860x_device_exit(struct pm860x_chip *chip);
> +
> +#endif /* __LINUX_MFD_88PM860X_H */
> --
> 1.5.6.5
--
Intel Open Source Technology Centre
http://oss.intel.com/
More information about the linux-arm-kernel
mailing list