diff options
author | Scott Peterson <speterson@nvidia.com> | 2013-01-23 15:53:01 -0800 |
---|---|---|
committer | Mandar Padmawar <mpadmawar@nvidia.com> | 2013-01-27 23:59:24 -0800 |
commit | c772f1bb3d1c6c4c787d0c0e5cdc24c6bf37705b (patch) | |
tree | 29f9ac21f42d4da351624c2e23dadeca30c11847 /drivers/mfd | |
parent | 767b28be1063c7057c71bbe999dc9dbc45651462 (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.c | 35 | ||||
-rw-r--r-- | drivers/mfd/tlv320aic3xxx-spi.c | 33 |
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 *) ® 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), |