summaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
authorScott Peterson <speterson@nvidia.com>2013-01-23 15:53:01 -0800
committerMandar Padmawar <mpadmawar@nvidia.com>2013-01-27 23:59:24 -0800
commitc772f1bb3d1c6c4c787d0c0e5cdc24c6bf37705b (patch)
tree29f9ac21f42d4da351624c2e23dadeca30c11847 /drivers/mfd
parent767b28be1063c7057c71bbe999dc9dbc45651462 (diff)
asoc: tegra: SPI interface for TI codec
Add support for accessing the TI aic3262 codec using the spi interface Change-Id: I30c72ac2bec5cd51e472f8f4e0750cd533d354a3 Signed-off-by: Scott Peterson <speterson@nvidia.com> Change-Id: I0dff26133be6c5f0ec36113a61e2b1b5b57b3339 Reviewed-on: http://git-master/r/194172 Tested-by: Vijay Mali <vmali@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/tlv320aic3xxx-core.c35
-rw-r--r--drivers/mfd/tlv320aic3xxx-spi.c33
2 files changed, 60 insertions, 8 deletions
diff --git a/drivers/mfd/tlv320aic3xxx-core.c b/drivers/mfd/tlv320aic3xxx-core.c
index 798e01073e06..d0a75841f1d3 100644
--- a/drivers/mfd/tlv320aic3xxx-core.c
+++ b/drivers/mfd/tlv320aic3xxx-core.c
@@ -68,6 +68,11 @@ struct aic3262_gpio aic3262_gpio_control[] = {
},
};
+/*Codec read count limit once*/
+#define CODEC_BULK_READ_MAX 128
+/*Ap read conut limit once*/
+#define CODEC_BULK_READ_LIMIT 63
+
int set_aic3xxx_book(struct aic3xxx *aic3xxx, int book)
{
int ret = 0;
@@ -157,9 +162,13 @@ int aic3xxx_bulk_read(struct aic3xxx *aic3xxx, unsigned int reg,
int count, u8 *buf)
{
int ret;
+ int count_temp = count;
union aic3xxx_reg_union *aic_reg = (union aic3xxx_reg_union *) &reg;
u8 book, page, offset;
+ if (count > CODEC_BULK_READ_MAX)
+ return -1;
+
page = aic_reg->aic3xxx_register.page;
book = aic_reg->aic3xxx_register.book;
offset = aic_reg->aic3xxx_register.offset;
@@ -180,7 +189,23 @@ int aic3xxx_bulk_read(struct aic3xxx *aic3xxx, unsigned int reg,
return ret;
}
}
- ret = regmap_bulk_read(aic3xxx->regmap, offset, buf, count);
+
+ while (count_temp) {
+ if (count_temp > CODEC_BULK_READ_LIMIT) {
+ ret = regmap_bulk_read(aic3xxx->regmap, offset,
+ buf, CODEC_BULK_READ_LIMIT);
+ offset += CODEC_BULK_READ_LIMIT;
+ buf += CODEC_BULK_READ_LIMIT;
+ count_temp -= CODEC_BULK_READ_LIMIT;
+ } else {
+ ret = regmap_bulk_read(aic3xxx->regmap, offset,
+ buf, count_temp);
+ offset += count_temp;
+ buf += count_temp;
+ count_temp -= count_temp;
+ }
+ }
+
mutex_unlock(&aic3xxx->io_lock);
return ret;
}
@@ -332,8 +357,8 @@ int aic3xxx_wait_bits(struct aic3xxx *aic3xxx, unsigned int reg,
};
if (!counter)
dev_err(aic3xxx->dev,
- "wait_bits timedout (%d millisecs). lastval 0x%x\n",
- timeout, status);
+ "wait_bits timedout (%d millisecs). lastval 0x%x val 0x%x\n",
+ timeout, status, val);
return counter;
}
EXPORT_SYMBOL_GPL(aic3xxx_wait_bits);
@@ -416,7 +441,8 @@ int aic3xxx_device_init(struct aic3xxx *aic3xxx, int irq)
aic3xxx->type);
aic3xxx->type = TLV320AIC3285;
default:
- dev_err(aic3xxx->dev, "Device is not a TLV320AIC3262");
+ dev_err(aic3xxx->dev, "Device is not a TLV320AIC3262 type=%d",
+ ret);
ret = -EINVAL;
goto err_return;
}
@@ -461,6 +487,7 @@ int aic3xxx_device_init(struct aic3xxx *aic3xxx, int irq)
aic3xxx_set_bits(aic3xxx, aic3262_gpio_control[i].reg,
aic3262_gpio_control[i].mask, 0x0);
}
+ aic3xxx->suspended = true;
/* codec interrupt */
if (aic3xxx->irq) {
diff --git a/drivers/mfd/tlv320aic3xxx-spi.c b/drivers/mfd/tlv320aic3xxx-spi.c
index 6f1426ab4cf7..cd0e506f7c47 100644
--- a/drivers/mfd/tlv320aic3xxx-spi.c
+++ b/drivers/mfd/tlv320aic3xxx-spi.c
@@ -10,12 +10,34 @@
#include <linux/mfd/tlv320aic3xxx-core.h>
struct regmap_config tlv320aic3xxx_spi_regmap = {
- .reg_bits = 8,
+ .reg_bits = 7,
+ .pad_bits = 1,
.val_bits = 8,
.cache_type = REGCACHE_NONE,
.read_flag_mask = 0x1,
};
+#ifdef CONFIG_PM
+static int aic3xxx_suspend(struct device *dev)
+{
+ struct aic3xxx *aic3xxx = dev_get_drvdata(dev);
+
+ aic3xxx->suspended = true;
+
+ return 0;
+}
+
+static int aic3xxx_resume(struct device *dev)
+{
+ struct aic3xxx *aic3xxx = dev_get_drvdata(dev);
+
+ aic3xxx->suspended = false;
+
+ return 0;
+}
+#endif
+
+
static int __devinit tlv320aic3xxx_spi_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
@@ -24,11 +46,9 @@ static int __devinit tlv320aic3xxx_spi_probe(struct spi_device *spi)
int ret;
switch (id->driver_data) {
-#ifdef CONFIG_SND_SOC_AIC3262
case TLV320AIC3262:
regmap_config = &tlv320aic3xxx_spi_regmap;
break;
-#endif
#ifdef CONFIG_MFD_AIC3285
case TLV320AIC3285:
regmap_config = &tlv320aic3285_spi_regmap;
@@ -68,16 +88,21 @@ static int __devexit tlv320aic3xxx_spi_remove(struct spi_device *spi)
}
static const struct spi_device_id aic3xxx_spi_ids[] = {
- {"tlv320aic3262", TLV320AIC3262},
+ {"tlv320aic3xxx", TLV320AIC3262},
{"tlv320aic3285", TLV320AIC3285},
{ }
};
MODULE_DEVICE_TABLE(spi, aic3xxx_spi_ids);
+static UNIVERSAL_DEV_PM_OPS(aic3xxx_pm_ops, aic3xxx_suspend, aic3xxx_resume,
+ NULL);
+
+
static struct spi_driver tlv320aic3xxx_spi_driver = {
.driver = {
.name = "tlv320aic3xxx",
.owner = THIS_MODULE,
+ .pm = &aic3xxx_pm_ops,
},
.probe = tlv320aic3xxx_spi_probe,
.remove = __devexit_p(tlv320aic3xxx_spi_remove),