diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2013-08-05 12:49:58 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-08-05 12:49:58 +0200 |
commit | f1355b4f574c62eaf0f5d1a974b1118127dcbeb6 (patch) | |
tree | c35d4f61cd58aad26b8cbce5314909c4d97a1782 /drivers | |
parent | 07afe7d0e00a9e14c5918a887161e6ccce542165 (diff) | |
parent | d93a43c8fcccdd09355737a1a4d6e5392d5f630d (diff) | |
download | barebox-f1355b4f574c62eaf0f5d1a974b1118127dcbeb6.tar.gz barebox-f1355b4f574c62eaf0f5d1a974b1118127dcbeb6.tar.xz |
Merge branch 'for-next/mfd'
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mfd/Kconfig | 6 | ||||
-rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
-rw-r--r-- | drivers/mfd/mc13xxx.c | 242 | ||||
-rw-r--r-- | drivers/mfd/mc34708.c | 295 |
4 files changed, 136 insertions, 408 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index afb87dbd2d..887376427c 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -6,16 +6,12 @@ config MFD_LP3972 config MFD_MC13XXX depends on I2C || SPI - bool "MC13XXX a.k.a. PMIC driver (MC13783, MC13892)" + bool "MC13XXX a.k.a. PMIC driver (MC13783, MC13892, MC34708)" config MFD_MC34704 depends on I2C bool "MC34704 PMIC driver" -config MFD_MC34708 - depends on I2C || SPI - bool "MC34708 PMIC driver" - config MFD_MC9SDZ60 depends on I2C bool "MC9SDZ60 driver" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 1afd52bd30..2ad766da1b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_MFD_LP3972) += lp3972.o obj-$(CONFIG_MFD_MC13XXX) += mc13xxx.o obj-$(CONFIG_MFD_MC34704) += mc34704.o -obj-$(CONFIG_MFD_MC34708) += mc34708.o obj-$(CONFIG_MFD_MC9SDZ60) += mc9sdz60.o obj-$(CONFIG_MFD_STMPE) += stmpe-i2c.o obj-$(CONFIG_MFD_SYSCON) += syscon.o diff --git a/drivers/mfd/mc13xxx.c b/drivers/mfd/mc13xxx.c index 466a11cb40..cf4c02aa05 100644 --- a/drivers/mfd/mc13xxx.c +++ b/drivers/mfd/mc13xxx.c @@ -28,19 +28,19 @@ #define DRIVERNAME "mc13xxx" -enum mc13xxx_mode { - MC13XXX_MODE_I2C, - MC13XXX_MODE_SPI, -}; - struct mc13xxx { struct cdev cdev; union { struct i2c_client *client; struct spi_device *spi; }; - enum mc13xxx_mode mode; int revision; + int (*reg_read)(struct mc13xxx*, u8, u32*); + int (*reg_write)(struct mc13xxx*, u8, u32); +}; + +struct mc13xxx_devtype { + int (*revision)(struct mc13xxx*); }; #define to_mc13xxx(a) container_of(a, struct mc13xxx, cdev) @@ -136,29 +136,13 @@ static int mc13xxx_i2c_reg_write(struct mc13xxx *mc13xxx, u8 reg, u32 val) int mc13xxx_reg_write(struct mc13xxx *mc13xxx, u8 reg, u32 val) { -#ifdef CONFIG_I2C - if (mc13xxx->mode == MC13XXX_MODE_I2C) - return mc13xxx_i2c_reg_write(mc13xxx, reg, val); -#endif -#ifdef CONFIG_SPI - if (mc13xxx->mode == MC13XXX_MODE_SPI) - return mc13xxx_spi_reg_write(mc13xxx, reg, val); -#endif - return -EINVAL; + return mc13xxx->reg_write(mc13xxx, reg, val); } EXPORT_SYMBOL(mc13xxx_reg_write); int mc13xxx_reg_read(struct mc13xxx *mc13xxx, u8 reg, u32 *val) { -#ifdef CONFIG_I2C - if (mc13xxx->mode == MC13XXX_MODE_I2C) - return mc13xxx_i2c_reg_read(mc13xxx, reg, val); -#endif -#ifdef CONFIG_SPI - if (mc13xxx->mode == MC13XXX_MODE_SPI) - return mc13xxx_spi_reg_read(mc13xxx, reg, val); -#endif - return -EINVAL; + return mc13xxx->reg_read(mc13xxx, reg, val); } EXPORT_SYMBOL(mc13xxx_reg_read); @@ -179,7 +163,7 @@ EXPORT_SYMBOL(mc13xxx_set_bits); static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags) { - struct mc13xxx *priv = to_mc13xxx(cdev); + struct mc13xxx *mc13xxx = to_mc13xxx(cdev); u32 *buf = _buf; size_t i = count >> 2; int err; @@ -187,7 +171,7 @@ static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, loff_t offse offset >>= 2; while (i) { - err = mc13xxx_reg_read(priv, offset, buf); + err = mc13xxx_reg_read(mc13xxx, offset, buf); if (err) return (ssize_t)err; buf++; @@ -225,13 +209,37 @@ static struct file_operations mc_fops = { .write = mc_write, }; -struct mc13892_rev { +static int __init mc13783_revision(struct mc13xxx *mc13xxx) +{ + unsigned int rev_id; + char revstr[5]; + int rev; + + mc13xxx_reg_read(mc13xxx, MC13XXX_REG_IDENTIFICATION, &rev_id); + + if (((rev_id >> 6) & 0x7) != 0x2) + return -ENODEV; + + + rev = (((rev_id & 0x18) >> 3) << 4) | (rev_id & 0x7); + /* Ver 0.2 is actually 3.2a. Report as 3.2 */ + if (rev == 0x02) { + rev = 0x32; + strcpy(revstr, "3.2a"); + } else + sprintf(revstr, "%d.%d", rev / 0x10, rev % 10); + + dev_info(mc_dev->cdev.dev, "Found MC13783 ID: 0x%06x [Rev: %s]\n", + rev_id, revstr); + + return rev; +} + +static struct __init { u16 rev_id; int rev; char *revstr; -}; - -static struct mc13892_rev mc13892_revisions[] = { +} mc13892_revisions[] = { { 0x01, MC13892_REVISION_1_0, "1.0" }, { 0x09, MC13892_REVISION_1_1, "1.1" }, { 0x0a, MC13892_REVISION_1_2, "1.2" }, @@ -245,132 +253,152 @@ static struct mc13892_rev mc13892_revisions[] = { { 0x1d, MC13892_REVISION_3_5, "3.5" }, }; -static int mc13xxx_query_revision(struct mc13xxx *mc13xxx) +static int __init mc13892_revision(struct mc13xxx *mc13xxx) { unsigned int rev_id; - char *chipname, revstr[5]; + char revstr[5]; int rev, i; mc13xxx_reg_read(mc13xxx, MC13XXX_REG_IDENTIFICATION, &rev_id); - /* Determine chip type by decode ICID bits */ - switch ((rev_id >> 6) & 0x7) { - case 2: - chipname = "MC13783"; - rev = (((rev_id & 0x18) >> 3) << 4) | (rev_id & 0x7); - /* Ver 0.2 is actually 3.2a. Report as 3.2 */ - if (rev == 0x02) { - rev = 0x32; - strcpy(revstr, "3.2a"); - } else - sprintf(revstr, "%d.%d", rev / 0x10, rev % 10); - break; - case 7: - chipname = "MC13892"; - for (i = 0; i < ARRAY_SIZE(mc13892_revisions); i++) - if ((rev_id & 0x1f) == mc13892_revisions[i].rev_id) - break; - - if (i == ARRAY_SIZE(mc13892_revisions)) - return -EINVAL; - - rev = mc13892_revisions[i].rev; - strcpy(revstr, mc13892_revisions[i].revstr); - - if (rev == MC13892_REVISION_2_0) { - if ((rev_id >> 9) & 0x3) { - rev = MC13892_REVISION_2_0a; - strcpy(revstr, "2.0a"); - } + if (((rev_id >> 6) & 0x7) != 0x7) + return -ENODEV; + + for (i = 0; i < ARRAY_SIZE(mc13892_revisions); i++) + if ((rev_id & 0x1f) == mc13892_revisions[i].rev_id) + break; + + if (i == ARRAY_SIZE(mc13892_revisions)) + return -ENOSYS; + + rev = mc13892_revisions[i].rev; + strcpy(revstr, mc13892_revisions[i].revstr); + + if (rev == MC13892_REVISION_2_0) { + if ((rev_id >> 9) & 0x3) { + rev = MC13892_REVISION_2_0a; + strcpy(revstr, "2.0a"); } - break; - default: - dev_info(mc_dev->cdev.dev, "No PMIC detected.\n"); - return -EINVAL; } - dev_info(mc_dev->cdev.dev, "Found %s ID: 0x%06x [Rev: %s]\n", - chipname, rev_id, revstr); - - mc13xxx->revision = rev; + dev_info(mc_dev->cdev.dev, "Found MC13892 ID: 0x%06x [Rev: %s]\n", + rev_id, revstr); return rev; } -static int mc_probe(struct device_d *dev, enum mc13xxx_mode mode) +static int __init mc34708_revision(struct mc13xxx *mc13xxx) { - int rev; + unsigned int rev_id; + + mc13xxx_reg_read(mc13xxx, MC13XXX_REG_IDENTIFICATION, &rev_id); + + if (rev_id > 0xfff) + return -ENODEV; + + dev_info(mc_dev->cdev.dev, "Found MC34708 ID: 0x%03x\n", rev_id); + + return (int)rev_id; +} + +static int __init mc13xxx_probe(struct device_d *dev) +{ + struct mc13xxx_devtype *devtype; + int ret, rev; if (mc_dev) return -EBUSY; - mc_dev = xzalloc(sizeof(struct mc13xxx)); - mc_dev->mode = mode; + ret = dev_get_drvdata(dev, (unsigned long *)&devtype); + if (ret) + return ret; + + mc_dev = xzalloc(sizeof(*mc_dev)); mc_dev->cdev.name = DRIVERNAME; - if (mode == MC13XXX_MODE_I2C) { + +#ifdef CONFIG_I2C + if (dev->bus == &i2c_bus) { mc_dev->client = to_i2c_client(dev); + mc_dev->reg_read = mc13xxx_i2c_reg_read; + mc_dev->reg_write = mc13xxx_i2c_reg_write; } - if (mode == MC13XXX_MODE_SPI) { +#endif +#ifdef CONFIG_SPI + if (dev->bus == &spi_bus) { mc_dev->spi = dev->type_data; mc_dev->spi->mode = SPI_MODE_0 | SPI_CS_HIGH; mc_dev->spi->bits_per_word = 32; mc_dev->spi->max_speed_hz = 20000000; + mc_dev->reg_read = mc13xxx_spi_reg_read; + mc_dev->reg_write = mc13xxx_spi_reg_write; } +#endif + mc_dev->cdev.size = 256; mc_dev->cdev.dev = dev; mc_dev->cdev.ops = &mc_fops; - rev = mc13xxx_query_revision(mc_dev); + rev = devtype->revision(mc_dev); if (rev < 0) { + dev_err(mc_dev->cdev.dev, "No PMIC detected.\n"); free(mc_dev); mc_dev = NULL; - return -EINVAL; + return rev; } + mc_dev->revision = rev; devfs_create(&mc_dev->cdev); return 0; } -static __maybe_unused struct of_device_id mc13892_dt_ids[] = { - { - .compatible = "fsl,mc13892", - }, { - .compatible = "fsl,mc13783", - }, { - /* sentinel */ - } +static struct mc13xxx_devtype mc13783_devtype = { + .revision = mc13783_revision, }; -#ifdef CONFIG_I2C -static int mc_i2c_probe(struct device_d *dev) -{ - return mc_probe(dev, MC13XXX_MODE_I2C); -} +static struct mc13xxx_devtype mc13892_devtype = { + .revision = mc13892_revision, +}; + +static struct mc13xxx_devtype mc34708_devtype = { + .revision = mc34708_revision, +}; -static struct driver_d mc_i2c_driver = { - .name = "mc13xxx-i2c", - .probe = mc_i2c_probe, - .of_compatible = DRV_OF_COMPAT(mc13892_dt_ids), +static struct platform_device_id mc13xxx_ids[] = { + { .name = "mc13783", .driver_data = (ulong)&mc13783_devtype, }, + { .name = "mc13892", .driver_data = (ulong)&mc13892_devtype, }, + { .name = "mc34708", .driver_data = (ulong)&mc34708_devtype, }, + { } }; -static int mc_i2c_init(void) +static __maybe_unused struct of_device_id mc13xxx_dt_ids[] = { + { .compatible = "fsl,mc13783", .data = (ulong)&mc13783_devtype, }, + { .compatible = "fsl,mc13892", .data = (ulong)&mc13892_devtype, }, + { .compatible = "fsl,mc34708", .data = (ulong)&mc34708_devtype, }, + { } +}; + +#ifdef CONFIG_I2C +static struct driver_d mc13xxx_i2c_driver = { + .name = "mc13xxx-i2c", + .probe = mc13xxx_probe, + .id_table = mc13xxx_ids, + .of_compatible = DRV_OF_COMPAT(mc13xxx_dt_ids), +}; + +static int __init mc13xxx_i2c_init(void) { - return i2c_driver_register(&mc_i2c_driver); + return i2c_driver_register(&mc13xxx_i2c_driver); } -device_initcall(mc_i2c_init); +device_initcall(mc13xxx_i2c_init); #endif #ifdef CONFIG_SPI -static int mc_spi_probe(struct device_d *dev) -{ - return mc_probe(dev, MC13XXX_MODE_SPI); -} - -static struct driver_d mc_spi_driver = { - .name = "mc13xxx-spi", - .probe = mc_spi_probe, - .of_compatible = DRV_OF_COMPAT(mc13892_dt_ids), +static struct driver_d mc13xxx_spi_driver = { + .name = "mc13xxx-spi", + .probe = mc13xxx_probe, + .id_table = mc13xxx_ids, + .of_compatible = DRV_OF_COMPAT(mc13xxx_dt_ids), }; -device_spi_driver(mc_spi_driver); +device_spi_driver(mc13xxx_spi_driver); #endif diff --git a/drivers/mfd/mc34708.c b/drivers/mfd/mc34708.c deleted file mode 100644 index 6fea2e2143..0000000000 --- a/drivers/mfd/mc34708.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2007 Sascha Hauer, Pengutronix - * 2009 Marc Kleine-Budde <mkl@pengutronix.de> - * - * 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. - * - * - */ - -#include <common.h> -#include <init.h> -#include <driver.h> -#include <xfuncs.h> -#include <errno.h> -#include <spi/spi.h> -#include <malloc.h> - -#include <i2c/i2c.h> -#include <mfd/mc34708.h> - -#define DRIVERNAME "mc34708" - -#define to_mc34708(a) container_of(a, struct mc34708, cdev) - -static struct mc34708 *mc_dev; - -struct mc34708 *mc34708_get(void) -{ - if (!mc_dev) - return NULL; - - return mc_dev; -} -EXPORT_SYMBOL(mc34708_get); - -#ifdef CONFIG_SPI -static int spi_rw(struct spi_device *spi, void * buf, size_t len) -{ - int ret; - - struct spi_transfer t = { - .tx_buf = (const void *)buf, - .rx_buf = buf, - .len = len, - .cs_change = 0, - .delay_usecs = 0, - }; - struct spi_message m; - - spi_message_init(&m); - spi_message_add_tail(&t, &m); - - if ((ret = spi_sync(spi, &m))) - return ret; - return 0; -} - -#define MXC_PMIC_REG_NUM(reg) (((reg) & 0x3f) << 25) -#define MXC_PMIC_WRITE (1 << 31) - -static int mc34708_spi_reg_read(struct mc34708 *mc34708, enum mc34708_reg reg, u32 *val) -{ - uint32_t buf; - - buf = MXC_PMIC_REG_NUM(reg); - - spi_rw(mc34708->spi, &buf, 4); - - *val = buf; - - return 0; -} - -static int mc34708_spi_reg_write(struct mc34708 *mc34708, enum mc34708_reg reg, u32 val) -{ - uint32_t buf = MXC_PMIC_REG_NUM(reg) | MXC_PMIC_WRITE | (val & 0xffffff); - - spi_rw(mc34708->spi, &buf, 4); - - return 0; -} -#endif - -#ifdef CONFIG_I2C -static int mc34708_i2c_reg_read(struct mc34708 *mc34708, enum mc34708_reg reg, u32 *val) -{ - u8 buf[3]; - int ret; - - ret = i2c_read_reg(mc34708->client, reg, buf, 3); - *val = buf[0] << 16 | buf[1] << 8 | buf[2] << 0; - - return ret == 3 ? 0 : ret; -} - -static int mc34708_i2c_reg_write(struct mc34708 *mc34708, enum mc34708_reg reg, u32 val) -{ - u8 buf[] = { - val >> 16, - val >> 8, - val >> 0, - }; - int ret; - - ret = i2c_write_reg(mc34708->client, reg, buf, 3); - - return ret == 3 ? 0 : ret; -} -#endif - -int mc34708_reg_write(struct mc34708 *mc34708, enum mc34708_reg reg, u32 val) -{ -#ifdef CONFIG_I2C - if (mc34708->mode == MC34708_MODE_I2C) - return mc34708_i2c_reg_write(mc34708, reg, val); -#endif -#ifdef CONFIG_SPI - if (mc34708->mode == MC34708_MODE_SPI) - return mc34708_spi_reg_write(mc34708, reg, val); -#endif - return -EINVAL; -} -EXPORT_SYMBOL(mc34708_reg_write); - -int mc34708_reg_read(struct mc34708 *mc34708, enum mc34708_reg reg, u32 *val) -{ -#ifdef CONFIG_I2C - if (mc34708->mode == MC34708_MODE_I2C) - return mc34708_i2c_reg_read(mc34708, reg, val); -#endif -#ifdef CONFIG_SPI - if (mc34708->mode == MC34708_MODE_SPI) - return mc34708_spi_reg_read(mc34708, reg, val); -#endif - return -EINVAL; -} -EXPORT_SYMBOL(mc34708_reg_read); - -int mc34708_set_bits(struct mc34708 *mc34708, enum mc34708_reg reg, u32 mask, u32 val) -{ - u32 tmp; - int err; - - err = mc34708_reg_read(mc34708, reg, &tmp); - tmp = (tmp & ~mask) | val; - - if (!err) - err = mc34708_reg_write(mc34708, reg, tmp); - - return err; -} -EXPORT_SYMBOL(mc34708_set_bits); - -static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, - loff_t offset, ulong flags) -{ - struct mc34708 *priv = to_mc34708(cdev); - u32 *buf = _buf; - size_t i = count >> 2; - int err; - - offset >>= 2; - - while (i) { - err = mc34708_reg_read(priv, offset, buf); - if (err) - return (ssize_t)err; - buf++; - i--; - offset++; - } - - return count; -} - -static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, - loff_t offset, ulong flags) -{ - struct mc34708 *mc34708 = to_mc34708(cdev); - const u32 *buf = _buf; - size_t i = count >> 2; - int err; - - offset >>= 2; - - while (i) { - err = mc34708_reg_write(mc34708, offset, *buf); - if (err) - return (ssize_t)err; - buf++; - i--; - offset++; - } - - return count; -} - -static struct file_operations mc_fops = { - .lseek = dev_lseek_default, - .read = mc_read, - .write = mc_write, -}; - -static int mc34708_query_revision(struct mc34708 *mc34708) -{ - unsigned int rev_id; - int rev; - - mc34708_reg_read(mc34708, 7, &rev_id); - - if (rev_id > 0xFFF) - return -EINVAL; - - rev = rev_id & 0xFFF; - - dev_info(mc_dev->cdev.dev, "MC34708 ID: 0x%04x\n", rev); - - mc34708->revision = rev; - - return rev; -} - -static int mc_probe(struct device_d *dev, enum mc34708_mode mode) -{ - int rev; - - if (mc_dev) - return -EBUSY; - - mc_dev = xzalloc(sizeof(struct mc34708)); - mc_dev->mode = mode; - mc_dev->cdev.name = DRIVERNAME; - if (mode == MC34708_MODE_I2C) { - mc_dev->client = to_i2c_client(dev); - } - if (mode == MC34708_MODE_SPI) { - mc_dev->spi = dev->type_data; - mc_dev->spi->mode = SPI_MODE_0 | SPI_CS_HIGH; - mc_dev->spi->bits_per_word = 32; - } - mc_dev->cdev.size = 256; - mc_dev->cdev.dev = dev; - mc_dev->cdev.ops = &mc_fops; - - rev = mc34708_query_revision(mc_dev); - if (rev < 0) { - free(mc_dev); - mc_dev = NULL; - return -EINVAL; - } - - devfs_create(&mc_dev->cdev); - - return 0; -} - -#ifdef CONFIG_I2C -static int mc_i2c_probe(struct device_d *dev) -{ - return mc_probe(dev, MC34708_MODE_I2C); -} - -static struct driver_d mc_i2c_driver = { - .name = "mc34708-i2c", - .probe = mc_i2c_probe, -}; - -static int mc_i2c_init(void) -{ - return i2c_driver_register(&mc_i2c_driver); -} - -device_initcall(mc_i2c_init); -#endif - -#ifdef CONFIG_SPI -static int mc_spi_probe(struct device_d *dev) -{ - return mc_probe(dev, MC34708_MODE_SPI); -} - -static struct driver_d mc_spi_driver = { - .name = "mc34708-spi", - .probe = mc_spi_probe, -}; -device_spi_driver(mc_spi_driver); -#endif |