drivers/mfd: remove unused tlv320aic3xxx driver

Change-Id: Iff5ded9be8f23566e9b04c8a34affd65f9099a74
Signed-off-by: Tao Huang <huangtao@rock-chips.com>
This commit is contained in:
Tao Huang
2018-11-05 10:24:26 +08:00
parent 7fe4460b45
commit 71b6be53eb
16 changed files with 0 additions and 9063 deletions

View File

@@ -1,683 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/mfd/core.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/machine.h>
#include <linux/gpio.h>
#include <linux/mfd/tlv320aic3262-core.h>
#include <linux/mfd/tlv320aic3262-registers.h>
#include <mach/gpio.h>
#include <mach/iomux.h>
#define DEBUG 1
struct aic3262_gpio
{
unsigned int reg;
u8 mask;
u8 shift;
};
struct aic3262_gpio aic3262_gpio_control[] = {
{
.reg = AIC3262_GPIO1_IO_CNTL,
.mask = AIC3262_GPIO_D6_D2,
.shift = AIC3262_GPIO_D2_SHIFT,
},
{
.reg = AIC3262_GPIO2_IO_CNTL,
.mask = AIC3262_GPIO_D6_D2,
.shift = AIC3262_GPIO_D2_SHIFT,
},
{
.reg = AIC3262_GPI1_EN,
.mask = AIC3262_GPI1_D2_D1,
.shift = AIC3262_GPIO_D1_SHIFT,
},
{
.reg = AIC3262_GPI2_EN,
.mask = AIC3262_GPI2_D5_D4,
.shift = AIC3262_GPIO_D4_SHIFT,
},
{
.reg = AIC3262_GPO1_OUT_CNTL,
.mask = AIC3262_GPO1_D4_D1,
.shift = AIC3262_GPIO_D1_SHIFT,
},
};
static int aic3262_read(struct aic3262 *aic3262, unsigned int reg,
int bytes, void *dest)
{
int ret;
//u8 *buf = dest;
// BUG_ON(bytes % 2);
BUG_ON(bytes <= 0);
ret = aic3262->read_dev(aic3262, reg, bytes, dest);
if (ret < 0)
return ret;
/* for (i = 0; i < bytes / 2; i++) {
dev_vdbg(aic3262->dev, "Read %04x from R%d(0x%x)\n",
buf[i], reg + i, reg + i);
}*/
return ret;
}
/**
* aic3262_reg_read: Read a single TLV320AIC3262 register.
*
* @aic3262: Device to read from.
* @reg: Register to read.
*/
int aic3262_reg_read(struct aic3262 *aic3262, unsigned int reg)
{
unsigned char val;
int ret;
mutex_lock(&aic3262->io_lock);
ret = aic3262_read(aic3262, reg, 1, &val);
mutex_unlock(&aic3262->io_lock);
if (ret < 0)
return ret;
else
return val;
}
EXPORT_SYMBOL_GPL(aic3262_reg_read);
/**
* aic3262_bulk_read: Read multiple TLV320AIC3262 registers
*
* @aic3262: Device to read from
* @reg: First register
* @count: Number of registers
* @buf: Buffer to fill. The data will be returned big endian.
*/
int aic3262_bulk_read(struct aic3262 *aic3262, unsigned int reg,
int count, u8 *buf)
{
int ret;
mutex_lock(&aic3262->io_lock);
ret = aic3262_read(aic3262, reg, count, buf);
mutex_unlock(&aic3262->io_lock);
return ret;
}
EXPORT_SYMBOL_GPL(aic3262_bulk_read);
static int aic3262_write(struct aic3262 *aic3262, unsigned int reg,
int bytes, const void *src)
{
//const u8 *buf = src;
// BUG_ON(bytes % 2);
BUG_ON(bytes <= 0);
/* for (i = 0; i < bytes / 2; i++) {
dev_vdbg(aic3262->dev, "Write %04x to R%d(0x%x)\n",
buf[i], reg + i, reg + i);
}*/
return aic3262->write_dev(aic3262, reg, bytes, src);
}
/**
* aic3262_reg_write: Write a single TLV320AIC3262 register.
*
* @aic3262: Device to write to.
* @reg: Register to write to.
* @val: Value to write.
*/
int aic3262_reg_write(struct aic3262 *aic3262, unsigned int reg,
unsigned char val)
{
int ret;
// val = cpu_to_be16(val);
mutex_lock(&aic3262->io_lock);
ret = aic3262_write(aic3262, reg, 1, &val);
mutex_unlock(&aic3262->io_lock);
return ret;
}
EXPORT_SYMBOL_GPL(aic3262_reg_write);
/**
* aic3262_bulk_write: Write multiple TLV320AIC3262 registers
*
* @aic3262: Device to write to
* @reg: First register
* @count: Number of registers
* @buf: Buffer to write from. Data must be big-endian formatted.
*/
int aic3262_bulk_write(struct aic3262 *aic3262, unsigned int reg,
int count, const u8 *buf)
{
int ret;
mutex_lock(&aic3262->io_lock);
ret = aic3262_write(aic3262, reg, count, buf);
mutex_unlock(&aic3262->io_lock);
return ret;
}
EXPORT_SYMBOL_GPL(aic3262_bulk_write);
/**
* aic3262_set_bits: Set the value of a bitfield in a TLV320AIC3262 register
*
* @aic3262: Device to write to.
* @reg: Register to write to.
* @mask: Mask of bits to set.
* @val: Value to set (unshifted)
*/
int aic3262_set_bits(struct aic3262 *aic3262, unsigned int reg,
unsigned char mask, unsigned char val)
{
int ret;
u8 r;
mutex_lock(&aic3262->io_lock);
ret = aic3262_read(aic3262, reg, 1, &r);
if (ret < 0)
goto out;
r &= ~mask;
r |= (val & mask);
ret = aic3262_write(aic3262, reg, 1, &r);
out:
mutex_unlock(&aic3262->io_lock);
return ret;
}
EXPORT_SYMBOL_GPL(aic3262_set_bits);
/* to be changed -- Mukund*/
static struct resource aic3262_codec_resources[] = {
{
.start = AIC3262_IRQ_HEADSET_DETECT,
.end = AIC3262_IRQ_SPEAKER_OVER_TEMP,
.flags = IORESOURCE_IRQ,
},
};
static struct resource aic3262_gpio_resources[] = {
{
.start = AIC3262_GPIO1,
.end = AIC3262_GPO1,
.flags = IORESOURCE_IRQ,
},
};
static struct mfd_cell aic3262_devs[] = {
{
.name = "tlv320aic3262-codec",
.num_resources = ARRAY_SIZE(aic3262_codec_resources),
.resources = aic3262_codec_resources,
},
{
.name = "tlv320aic3262-gpio",
.num_resources = ARRAY_SIZE(aic3262_gpio_resources),
.resources = aic3262_gpio_resources,
.pm_runtime_no_callbacks = true,
},
};
#ifdef CONFIG_PM
static int aic3262_suspend(struct device *dev)
{
struct aic3262 *aic3262 = dev_get_drvdata(dev);
/* Don't actually go through with the suspend if the CODEC is
* still active (eg, for audio passthrough from CP. */
// ret = aic3262_reg_read(aic3262, 20AIC3262_POWER_MANAGEMENT_1);
/* if (ret < 0) {
dev_err(dev, "Failed to read power status: %d\n", ret);
} else if (ret & TLV320AIC3262_VMID_SEL_MASK) {
dev_dbg(dev, "CODEC still active, ignoring suspend\n");
return 0;
}
*/
/* GPIO configuration state is saved here since we may be configuring
* the GPIO alternate functions even if we're not using the gpiolib
* driver for them.
*/
// ret = aic3262_read(aic3262, TLV320AIC3262_GPIO_1, TLV320AIC3262_NUM_GPIO_REGS * 2,
// &aic3262->gpio_regs);
/* if (ret < 0)
dev_err(dev, "Failed to save GPIO registers: %d\n", ret);*/
/* Explicitly put the device into reset in case regulators
* don't get disabled in order to ensure consistent restart.
*/
// aic3262_reg_write(aic3262, TLV320AIC3262_SOFTWARE_RESET, 0x8994);
aic3262->suspended = true;
return 0;
}
static int aic3262_resume(struct device *dev)
{
struct aic3262 *aic3262 = dev_get_drvdata(dev);
/* We may have lied to the PM core about suspending */
/* if (!aic3262->suspended)
return 0;
ret = aic3262_write(aic3262, TLV320AIC3262_INTERRUPT_STATUS_1_MASK,
TLV320AIC3262_NUM_IRQ_REGS * 2, &aic3262->irq_masks_cur);
if (ret < 0)
dev_err(dev, "Failed to restore interrupt masks: %d\n", ret);
ret = aic3262_write(aic3262, TLV320AIC3262_GPIO_1, TLV320AIC3262_NUM_GPIO_REGS * 2,
&aic3262->gpio_regs);
if (ret < 0)
dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
*/
aic3262->suspended = false;
return 0;
}
#endif
/*
* Instantiate the generic non-control parts of the device.
*/
static int aic3262_device_init(struct aic3262 *aic3262, int irq)
{
struct aic3262_pdata *pdata = aic3262->dev->platform_data;
const char *devname;
int ret, i;
u8 revID, pgID;
unsigned int naudint = 0;
u8 resetVal = 1;
//printk("aic3262_device_init beginning\n");
mutex_init(&aic3262->io_lock);
dev_set_drvdata(aic3262->dev, aic3262);
if(pdata){
if(pdata->gpio_reset){
ret = gpio_request(pdata->gpio_reset,"aic3262-reset-pin");
if(ret != 0){
dev_err(aic3262->dev,"not able to acquire gpio %d for reseting the AIC3262 \n", pdata->gpio_reset);
goto err_return;
}
rk30_mux_api_set(GPIO0B7_I2S8CHSDO3_NAME, GPIO0B_GPIO0B7);
gpio_direction_output(pdata->gpio_reset, 1);
msleep(5);
gpio_direction_output(pdata->gpio_reset, 0);
msleep(5);
gpio_direction_output(pdata->gpio_reset, 1);
// gpio_set_value(pdata->gpio_reset, 0);
msleep(5);
}
}
/* run the codec through software reset */
ret = aic3262_reg_write(aic3262, AIC3262_RESET_REG, resetVal);
if (ret < 0) {
dev_err(aic3262->dev, "Could not write to AIC3262 register\n");
goto err_return;
}
msleep(10);
ret = aic3262_reg_read(aic3262, AIC3262_REV_PG_ID);
if (ret < 0) {
dev_err(aic3262->dev, "Failed to read ID register\n");
goto err_return;
}
revID = (ret & AIC3262_REV_MASK) >> AIC3262_REV_SHIFT;
pgID = (ret & AIC3262_PG_MASK) >> AIC3262_PG_SHIFT;
switch (revID ) {
case 3:
devname = "TLV320AIC3262";
if (aic3262->type != TLV320AIC3262)
dev_warn(aic3262->dev, "Device registered as type %d\n",
aic3262->type);
aic3262->type = TLV320AIC3262;
break;
default:
dev_err(aic3262->dev, "Device is not a TLV320AIC3262, ID is %x\n",
ret);
ret = -EINVAL;
goto err_return;
}
dev_info(aic3262->dev, "%s revision %c\n", devname, 'D' + ret);
printk("aic3262_device_init %s revision %c\n", devname, 'D' + ret);
if (pdata) {
if(pdata->gpio_irq == 1) {
naudint = gpio_to_irq(pdata->naudint_irq);
gpio_request(pdata->naudint_irq,"aic3262-gpio-irq");
gpio_direction_input(pdata->naudint_irq);
}
else {
naudint = pdata->naudint_irq;
}
aic3262->irq = naudint;
aic3262->irq_base = pdata->irq_base;
for(i = 0; i < AIC3262_NUM_GPIO;i++)
{
if(pdata->gpio[i].used)
{
if(pdata->gpio[i].in) // direction is input
{
// set direction to input for GPIO, and enable for GPI
aic3262_set_bits(aic3262, aic3262_gpio_control[i].reg,
aic3262_gpio_control[i].mask, 0x1 << aic3262_gpio_control[i].shift);
if(pdata->gpio[i].in_reg) // Some input modes, does not need extra registers to be written
aic3262_set_bits(aic3262, pdata->gpio[i].in_reg,
pdata->gpio[i].in_reg_bitmask,
pdata->gpio[i].value << pdata->gpio[i].in_reg_shift);
}
else // direction is output
{
aic3262_set_bits(aic3262, aic3262_gpio_control[i].reg,
aic3262_gpio_control[i].mask, pdata->gpio[i].value << aic3262_gpio_control[i].shift);
}
}
else // Disable the gpio/gpi/gpo
aic3262_set_bits(aic3262, aic3262_gpio_control[i].reg, aic3262_gpio_control[i].mask, 0x0);
}
}
if(naudint) {
/* codec interrupt */
ret = aic3262_irq_init(aic3262);
if(ret)
goto err_irq;
}
ret = mfd_add_devices(aic3262->dev, -1,
aic3262_devs, ARRAY_SIZE(aic3262_devs),
NULL, 0);
if (ret != 0) {
dev_err(aic3262->dev, "Failed to add children: %d\n", ret);
goto err_irq;
}
printk("aic3262_device_init added mfd devices \n");
pm_runtime_enable(aic3262->dev);
pm_runtime_resume(aic3262->dev);
return 0;
err_irq:
aic3262_irq_exit(aic3262);
//err:
// mfd_remove_devices(aic3262->dev);
err_return:
kfree(aic3262);
return ret;
}
static void aic3262_device_exit(struct aic3262 *aic3262)
{
pm_runtime_disable(aic3262->dev);
mfd_remove_devices(aic3262->dev);
aic3262_irq_exit(aic3262);
kfree(aic3262);
}
static int aic3262_i2c_read_device(struct aic3262 *aic3262, unsigned int reg,
int bytes, void *dest)
{
struct i2c_client *i2c = aic3262->control_data;
aic326x_reg_union *aic_reg = (aic326x_reg_union *) &reg;
char *value;
int ret;
u8 buf[2];
u8 page, book, offset;
page = aic_reg->aic326x_register.page;
book = aic_reg->aic326x_register.book;
offset = aic_reg->aic326x_register.offset;
if(aic3262->book_no != book) // change in book required.
{
// We should change to page 0.
// Change the book by writing to offset 127 of page 0
// Change the page back to whatever was set before change page
buf[0] = 0x0;
buf[1] = 0x0;
ret = i2c_master_send(i2c, (unsigned char *)buf, 2);
if (ret < 0)
return ret;
if (ret != 2)
return -EIO;
buf[0] = 127;
buf[1] = book;
ret = i2c_master_send(i2c, (unsigned char *)buf, 2);
if (ret < 0)
return ret;
if (ret != 2)
return -EIO;
aic3262->book_no = book;
aic3262->page_no = 0x0;// To force a page change in the following if
}
if (aic3262->page_no != page) {
buf[0] = 0x0;
buf[1] = page;
ret = i2c_master_send(i2c, (unsigned char *) buf, 2);
if (ret < 0)
return ret;
if (ret != 2)
return -EIO;
aic3262->page_no = page;
}
// Send the required offset
buf[0] = offset ;
ret = i2c_master_send(i2c, (unsigned char *)buf, 1);
if (ret < 0)
return ret;
if (ret != 1)
return -EIO;
ret = i2c_master_recv(i2c, dest, bytes);
value = dest;
if (ret < 0)
return ret;
if (ret != bytes)
return -EIO;
return ret;
}
static int aic3262_i2c_write_device(struct aic3262 *aic3262, unsigned int reg,
int bytes, const void *src)
{
struct i2c_client *i2c = aic3262->control_data;
int ret;
//char *value;
aic326x_reg_union *aic_reg = (aic326x_reg_union *) &reg;
//struct i2c_msg xfer[2];
u8 buf[2];
u8 write_buf[bytes + 1];
u8 page, book, offset;
page = aic_reg->aic326x_register.page;
book = aic_reg->aic326x_register.book;
offset = aic_reg->aic326x_register.offset;
if(aic3262->book_no != book) // change in book required.
{
// We should change to page 0.
// Change the book by writing to offset 127 of page 0
// Change the page back to whatever was set before change page
buf[0] = 0x0;
buf[1] = 0x0;
ret = i2c_master_send(i2c, (unsigned char *)buf, 2);
if (ret < 0)
return ret;
if (ret != 2)
return -EIO;
buf[0] = 127;
buf[1] = book;
ret = i2c_master_send(i2c, (unsigned char *)buf, 2);
if (ret < 0)
return ret;
if (ret != 2)
return -EIO;
aic3262->book_no = book;
aic3262->page_no = 0x0;// To force a page change in the following if
}
if (aic3262->page_no != page) {
buf[0] = 0x0;
buf[1] = page;
ret = i2c_master_send(i2c, (unsigned char *) buf, 2);
if (ret < 0)
return ret;
if (ret != 2)
return -EIO;
aic3262->page_no = page;
}
// value = (char *) src;
//ret = i2c_transfer(i2c->adapter, xfer, 2);
//printk("%s:write ret = %d\n",__func__, ret);
// send the offset as first message
/* xfer[0].addr = i2c->addr;
xfer[0].flags = i2c->flags & I2C_M_TEN;
xfer[0].len = 1;
xfer[0].buf = (char *)&offset;
// Send the values in bulk
xfer[1].addr = i2c->addr;
xfer[1].flags = i2c->flags & I2C_M_TEN;
xfer[1].len = bytes;
xfer[1].buf = (char *)src;
ret = i2c_transfer(i2c->adapter, xfer, 2);*/
/* buf[0] = offset;
memcpy(&buf[1], src, bytes);*/
// ret = i2c_master_send(i2c, (unsigned char *)buf, 1);
// printk("%s:write offset ret = %d\n",__func__, ret);
// ret = i2c_master_send(i2c, (unsigned char *)src, bytes);
/* value = (char *) src;
buf[0] = offset;
buf[1] = *value;
ret = i2c_master_send(i2c, buf, 2); */
write_buf[0] = offset;
memcpy(&write_buf[1], src, bytes);
ret = i2c_master_send(i2c, write_buf, bytes + 1);
if (ret < 0)
return ret;
if (ret != (bytes + 1) )
return -EIO;
return 0;
}
static int aic3262_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct aic3262 *aic3262;
printk("%s: entered \n", __FUNCTION__);
aic3262 = kzalloc(sizeof(struct aic3262), GFP_KERNEL);
if (aic3262 == NULL)
return -ENOMEM;
printk("%s: allocated memory \n", __FUNCTION__);
i2c_set_clientdata(i2c, aic3262);
aic3262->dev = &i2c->dev;
aic3262->control_data = i2c;
aic3262->read_dev = aic3262_i2c_read_device;
aic3262->write_dev = aic3262_i2c_write_device;
// aic3262->irq = i2c->irq;
aic3262->type = id->driver_data;
aic3262->book_no = 255;
aic3262->page_no = 255;
return aic3262_device_init(aic3262, i2c->irq);
}
static int aic3262_i2c_remove(struct i2c_client *i2c)
{
struct aic3262 *aic3262 = i2c_get_clientdata(i2c);
aic3262_device_exit(aic3262);
return 0;
}
static const struct i2c_device_id aic3262_i2c_id[] = {
{ "tlv320aic3262", TLV320AIC3262 },
{ }
};
MODULE_DEVICE_TABLE(i2c, aic3262_i2c_id);
static UNIVERSAL_DEV_PM_OPS(aic3262_pm_ops, aic3262_suspend, aic3262_resume,
NULL);
static struct i2c_driver aic3262_i2c_driver = {
.driver = {
.name = "tlv320aic3262",
.owner = THIS_MODULE,
.pm = &aic3262_pm_ops,
},
.probe = aic3262_i2c_probe,
.remove = aic3262_i2c_remove,
.id_table = aic3262_i2c_id,
};
static int __init aic3262_i2c_init(void)
{
int ret;
printk("aic3262_mfd i2c_init \n");
ret = i2c_add_driver(&aic3262_i2c_driver);
if (ret != 0)
pr_err("Failed to register aic3262 I2C driver: %d\n", ret);
return ret;
}
module_init(aic3262_i2c_init);
static void __exit aic3262_i2c_exit(void)
{
i2c_del_driver(&aic3262_i2c_driver);
}
module_exit(aic3262_i2c_exit);
MODULE_DESCRIPTION("Core support for the TLV320AIC3262 audio CODEC");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mukund Navada <navada@ti.comm>");

View File

@@ -1,205 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/mfd/core.h>
#include <linux/interrupt.h>
#include <linux/mfd/tlv320aic3262-core.h>
#include <linux/mfd/tlv320aic3262-registers.h>
#include <linux/delay.h>
struct aic3262_irq_data {
int mask;
int status;
};
static struct aic3262_irq_data aic3262_irqs[] = {
{
.mask = AIC3262_HEADSET_IN_MASK,
.status = AIC3262_HEADSET_PLUG_UNPLUG_INT,
},
{
.mask = AIC3262_BUTTON_PRESS_MASK,
.status = AIC3262_BUTTON_PRESS_INT,
},
{
.mask = AIC3262_DAC_DRC_THRES_MASK,
.status = AIC3262_LEFT_DRC_THRES_INT | AIC3262_RIGHT_DRC_THRES_INT,
},
{
.mask = AIC3262_AGC_NOISE_MASK,
.status = AIC3262_LEFT_AGC_NOISE_INT | AIC3262_RIGHT_AGC_NOISE_INT,
},
{
.mask = AIC3262_OVER_CURRENT_MASK,
.status = AIC3262_LEFT_OUTPUT_DRIVER_OVERCURRENT_INT
| AIC3262_RIGHT_OUTPUT_DRIVER_OVERCURRENT_INT,
},
{
.mask = AIC3262_OVERFLOW_MASK,
.status = AIC3262_LEFT_DAC_OVERFLOW_INT | AIC3262_RIGHT_DAC_OVERFLOW_INT
| AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT | AIC3262_LEFT_ADC_OVERFLOW_INT
| AIC3262_RIGHT_ADC_OVERFLOW_INT | AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT,
},
{
.mask = AIC3262_SPK_OVERCURRENT_MASK,
.status = AIC3262_SPK_OVER_CURRENT_INT,
},
};
struct aic3262_gpio_data {
};
static inline struct aic3262_irq_data *irq_to_aic3262_irq(struct aic3262 *aic3262,
int irq)
{
return &aic3262_irqs[irq - aic3262->irq_base];
}
static void aic3262_irq_lock(struct irq_data *data)
{
struct aic3262 *aic3262 = irq_data_get_irq_chip_data(data);
mutex_lock(&aic3262->irq_lock);
}
static void aic3262_irq_sync_unlock(struct irq_data *data)
{
struct aic3262 *aic3262 = irq_data_get_irq_chip_data(data);
/* write back to hardware any change in irq mask */
if (aic3262->irq_masks_cur != aic3262->irq_masks_cache) {
aic3262->irq_masks_cache = aic3262->irq_masks_cur;
aic3262_reg_write(aic3262, AIC3262_INT1_CNTL,
aic3262->irq_masks_cur);
}
mutex_unlock(&aic3262->irq_lock);
}
static void aic3262_irq_unmask(struct irq_data *data)
{
struct aic3262 *aic3262 = irq_data_get_irq_chip_data(data);
struct aic3262_irq_data *irq_data = irq_to_aic3262_irq(aic3262, data->irq);
aic3262->irq_masks_cur |= irq_data->mask;
}
static void aic3262_irq_mask(struct irq_data *data)
{
struct aic3262 *aic3262 = irq_data_get_irq_chip_data(data);
struct aic3262_irq_data *irq_data = irq_to_aic3262_irq(aic3262, data->irq);
aic3262->irq_masks_cur &= ~irq_data->mask;
}
static struct irq_chip aic3262_irq_chip = {
.name = "tlv320aic3262",
.irq_bus_lock = aic3262_irq_lock,
.irq_bus_sync_unlock = aic3262_irq_sync_unlock,
.irq_mask = aic3262_irq_mask,
.irq_unmask = aic3262_irq_unmask,
};
static irqreturn_t aic3262_irq_thread(int irq, void *data)
{
struct aic3262 *aic3262 = data;
u8 status[4];
int i=0;
// Reading the sticky bit registers acknowledges the interrupt to the device */
aic3262_bulk_read(aic3262, AIC3262_INT_STICKY_FLAG1, 4, status);
/* report */
if(status[2] & aic3262_irqs[AIC3262_IRQ_HEADSET_DETECT].status) // 0
{
handle_nested_irq(aic3262->irq_base);
}
if(status[2] & aic3262_irqs[AIC3262_IRQ_BUTTON_PRESS].status) // 1
handle_nested_irq(aic3262->irq_base + 1);
if(status[2] & aic3262_irqs[AIC3262_IRQ_DAC_DRC].status) // 2
handle_nested_irq(aic3262->irq_base + 2);
if(status[3] & aic3262_irqs[AIC3262_IRQ_AGC_NOISE].status) // 3
handle_nested_irq(aic3262->irq_base + 3);
if(status[2] & aic3262_irqs[AIC3262_IRQ_OVER_CURRENT].status) // 4
handle_nested_irq(aic3262->irq_base + 4);
if(status[0] & aic3262_irqs[AIC3262_IRQ_OVERFLOW_EVENT].status) // 5
handle_nested_irq(aic3262->irq_base + 5);
if(status[3] & aic3262_irqs[AIC3262_IRQ_SPEAKER_OVER_TEMP].status) // 6
handle_nested_irq(aic3262->irq_base + 6);
/* ack unmasked irqs */
/* No need to acknowledge the interrupt on AIC3262 */
return IRQ_HANDLED;
}
int aic3262_irq_init(struct aic3262 *aic3262)
{
int cur_irq, ret;
mutex_init(&aic3262->irq_lock);
/* mask the individual interrupt sources */
aic3262->irq_masks_cur = 0x0;
aic3262->irq_masks_cache = 0x0;
aic3262_reg_write(aic3262, AIC3262_INT1_CNTL, 0x0);
if (!aic3262->irq) {
dev_warn(aic3262->dev,
"no interrupt specified, no interrupts\n");
aic3262->irq_base = 0;
return 0;
}
if (!aic3262->irq_base) {
dev_err(aic3262->dev,
"no interrupt base specified, no interrupts\n");
return 0;
}
/* Register them with genirq */
for (cur_irq = aic3262->irq_base;
cur_irq < aic3262->irq_base + ARRAY_SIZE(aic3262_irqs);
cur_irq++) {
irq_set_chip_data(cur_irq, aic3262);
irq_set_chip_and_handler(cur_irq, &aic3262_irq_chip,
handle_edge_irq);
irq_set_nested_thread(cur_irq, 1);
/* ARM needs us to explicitly flag the IRQ as valid
* and will set them noprobe when we do so. */
#ifdef CONFIG_ARM
set_irq_flags(cur_irq, IRQF_VALID);
#else
set_irq_noprobe(cur_irq);
#endif
}
ret = request_threaded_irq(aic3262->irq, NULL, aic3262_irq_thread,
IRQF_TRIGGER_RISING,
"tlv320aic3262", aic3262);
if (ret) {
dev_err(aic3262->dev, "failed to request IRQ %d: %d\n",
aic3262->irq, ret);
return ret;
}
return 0;
}
EXPORT_SYMBOL(aic3262_irq_init);
void aic3262_irq_exit(struct aic3262 *aic3262)
{
if (aic3262->irq)
free_irq(aic3262->irq, aic3262);
}
EXPORT_SYMBOL(aic3262_irq_exit);

View File

@@ -1,257 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __MFD_AIC3262_CORE_H__
#define __MFD_AIC3262_CORE_H__
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
enum aic3262_type {
TLV320AIC3262 = 0,
};
#define AIC3262_IRQ_HEADSET_DETECT 0
#define AIC3262_IRQ_BUTTON_PRESS 1
#define AIC3262_IRQ_DAC_DRC 2
#define AIC3262_IRQ_AGC_NOISE 3
#define AIC3262_IRQ_OVER_CURRENT 4
#define AIC3262_IRQ_OVERFLOW_EVENT 5
#define AIC3262_IRQ_SPEAKER_OVER_TEMP 6
#define AIC3262_GPIO1 7
#define AIC3262_GPIO2 8
#define AIC3262_GPI1 9
#define AIC3262_GPI2 10
#define AIC3262_GPO1 11
typedef union aic326x_reg_union {
struct aic326x_reg{
u8 offset;
u8 page;
u8 book;
u8 reserved;
}aic326x_register;
unsigned int aic326x_register_int;
}aic326x_reg_union;
/**************************** ************************************/
/*
*****************************************************************************
* Structures Definitions
*****************************************************************************
*/
/*
*----------------------------------------------------------------------------
* @struct aic3262_setup_data |
* i2c specific data setup for AIC3262.
* @field unsigned short |i2c_address |
* Unsigned short for i2c address.
*----------------------------------------------------------------------------
*/
struct aic3262_setup_data {
unsigned short i2c_address;
};
/* GPIO API */
#define AIC3262_NUM_GPIO 5 // include 2 GPI and 1 GPO pins
enum {
AIC3262_GPIO1_FUNC_DISABLED = 0,
AIC3262_GPIO1_FUNC_INPUT = 1,
AIC3262_GPIO1_FUNC_OUTPUT = 3,
AIC3262_GPIO1_FUNC_CLOCK_OUTPUT = 4,
AIC3262_GPIO1_FUNC_INT1_OUTPUT = 5,
AIC3262_GPIO1_FUNC_INT2_OUTPUT = 6,
AIC3262_GPIO1_FUNC_ADC_MOD_CLK_OUTPUT = 10,
AIC3262_GPIO1_FUNC_SAR_ADC_INTERRUPT = 12,
AIC3262_GPIO1_FUNC_ASI1_DATA_OUTPUT = 15,
AIC3262_GPIO1_FUNC_ASI1_WCLK = 16,
AIC3262_GPIO1_FUNC_ASI1_BCLK = 17,
AIC3262_GPIO1_FUNC_ASI2_WCLK = 18,
AIC3262_GPIO1_FUNC_ASI2_BCLK = 19,
AIC3262_GPIO1_FUNC_ASI3_WCLK = 20,
AIC3262_GPIO1_FUNC_ASI3_BCLK = 21
};
enum {
AIC3262_GPIO2_FUNC_DISABLED = 0,
AIC3262_GPIO2_FUNC_INPUT = 1,
AIC3262_GPIO2_FUNC_OUTPUT = 3,
AIC3262_GPIO2_FUNC_CLOCK_OUTPUT = 4,
AIC3262_GPIO2_FUNC_INT1_OUTPUT = 5,
AIC3262_GPIO2_FUNC_INT2_OUTPUT = 6,
AIC3262_GPIO2_FUNC_ADC_MOD_CLK_OUTPUT = 10,
AIC3262_GPIO2_FUNC_SAR_ADC_INTERRUPT = 12,
AIC3262_GPIO2_FUNC_ASI1_DATA_OUTPUT = 15,
AIC3262_GPIO2_FUNC_ASI1_WCLK = 16,
AIC3262_GPIO2_FUNC_ASI1_BCLK = 17,
AIC3262_GPIO2_FUNC_ASI2_WCLK = 18,
AIC3262_GPIO2_FUNC_ASI2_BCLK = 19,
AIC3262_GPIO2_FUNC_ASI3_WCLK = 20,
AIC3262_GPIO2_FUNC_ASI3_BCLK = 21
};
enum {
AIC3262_GPO1_FUNC_DISABLED = 0,
AIC3262_GPO1_FUNC_MSO_OUTPUT_FOR_SPI = 1,
AIC3262_GPO1_FUNC_GENERAL_PURPOSE_OUTPUT= 2,
AIC3262_GPO1_FUNC_CLOCK_OUTPUT = 3,
AIC3262_GPO1_FUNC_INT1_OUTPUT = 4,
AIC3262_GPO1_FUNC_INT2_OUTPUT = 5,
AIC3262_GPO1_FUNC_ADC_MOD_CLK_OUTPUT = 7,
AIC3262_GPO1_FUNC_SAR_ADC_INTERRUPT = 12,
AIC3262_GPO1_FUNC_ASI1_DATA_OUTPUT = 15,
};
/*
*----------------------------------------------------------------------------
* @struct aic3262_configs |
* AIC3262 initialization data which has register offset and register
* value.
* @field u8 | book_no |
* AIC3262 Book Number Offsets required for initialization..
* @field u16 | reg_offset |
* AIC3262 Register offsets required for initialization..
* @field u8 | reg_val |
* value to set the AIC3262 register to initialize the AIC3262.
*----------------------------------------------------------------------------
*/
struct aic3262_configs {
u8 book_no;
u16 reg_offset;
u8 reg_val;
};
/*
*----------------------------------------------------------------------------
* @struct aic3262_rate_divs |
* Setting up the values to get different freqencies
*
* @field u32 | mclk |
* Master clock
* @field u32 | rate |
* sample rate
* @field u8 | p_val |
* value of p in PLL
* @field u32 | pll_j |
* value for pll_j
* @field u32 | pll_d |
* value for pll_d
* @field u32 | dosr |
* value to store dosr
* @field u32 | ndac |
* value for ndac
* @field u32 | mdac |
* value for mdac
* @field u32 | aosr |
* value for aosr
* @field u32 | nadc |
* value for nadc
* @field u32 | madc |
* value for madc
* @field u32 | blck_N |
* value for block N
*/
struct aic3262 {
struct mutex io_lock;
struct mutex irq_lock;
enum aic3262_type type;
struct device *dev;
int (*read_dev)(struct aic3262 *aic3262, unsigned int reg,
int bytes, void *dest);
int (*write_dev)(struct aic3262 *aic3262, unsigned int reg,
int bytes, const void *src);
void *control_data;
// int gpio_base;
unsigned int irq;
unsigned int irq_base;
u8 irq_masks_cur;
u8 irq_masks_cache;
/* Used over suspend/resume */
bool suspended;
u8 book_no;
u8 page_no;
};
struct aic3262_gpio_setup
{
u8 used; // GPIO, GPI and GPO is used in the board, used = 1 else 0
u8 in; // GPIO is used as input, in = 1 else in = 0. GPI in = 1, GPO in = 0
unsigned int in_reg; // if GPIO is input, register to write the mask to.
u8 in_reg_bitmask; // bitmask for 'value' to be written into in_reg
u8 in_reg_shift; // bits to shift to write 'value' into in_reg
u8 value; // value to be written gpio_control_reg if GPIO is output, in_reg if its input
};
struct aic3262_pdata {
unsigned int audio_mclk1;
unsigned int audio_mclk2;
unsigned int gpio_irq; /* whether AIC3262 interrupts the host AP on a GPIO pin of AP */
unsigned int gpio_reset; /* is the codec being reset by a gpio [host] pin, if yes provide the number. */
struct aic3262_gpio_setup *gpio;/* all gpio configuration */
int naudint_irq; /* audio interrupt */
unsigned int irq_base;
};
static inline int aic3262_request_irq(struct aic3262 *aic3262, int irq,
irq_handler_t handler, unsigned long irqflags,const char *name,
void *data)
{
if (!aic3262->irq_base)
return -EINVAL;
return request_threaded_irq(aic3262->irq_base + irq, NULL, handler,
irqflags, name, data);
}
static inline void aic3262_free_irq(struct aic3262 *aic3262, int irq,
void *data)
{
if (!aic3262->irq_base)
return;
free_irq(aic3262->irq_base + irq, data);
}
/* Device I/O API */
int aic3262_reg_read(struct aic3262 *aic3262, unsigned int reg);
int aic3262_reg_write(struct aic3262 *aic3262, unsigned int reg,
unsigned char val);
int aic3262_set_bits(struct aic3262 *aic3262, unsigned int reg,
unsigned char mask, unsigned char val);
int aic3262_bulk_read(struct aic3262 *aic3262, unsigned int reg,
int count, u8 *buf);
int aic3262_bulk_write(struct aic3262 *aic3262, unsigned int reg,
int count, const u8 *buf);
/* Helper to save on boilerplate */
/*static inline int aic3262_request_irq(struct aic3262 *aic3262, int irq,
irq_handler_t handler, const char *name,
void *data)
{
if (!aic3262->irq_base)
return -EINVAL;
return request_threaded_irq(aic3262->irq_base + irq, NULL, handler,
IRQF_TRIGGER_RISING, name,
data);
}
static inline void aic3262_free_irq(struct aic3262 *aic3262, int irq, void *data)
{
if (!aic3262->irq_base)
return;
free_irq(aic3262->irq_base + irq, data);
}
*/
int aic3262_irq_init(struct aic3262 *aic3262);
void aic3262_irq_exit(struct aic3262 *aic3262);
#endif

View File

@@ -1,302 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __MFD_AIC3262_REGISTERS_H__
#define __MFD_AIC3262_REGISTERS_H__
/*typedef union aic326x_reg_union {
struct aic326x_reg{
u8 reserved;
u8 book;
u8 page;
u8 offset;
}aic326x_register;
unsigned int aic326x_register_int;
}aic326x_reg_union;*/
#define MAKE_REG(book, page, offset) (unsigned int)((book << 16)|(page << 8)|offset)
/* ****************** Book 0 Registers **************************************/
/* ****************** Page 0 Registers **************************************/
#define AIC3262_PAGE_SEL_REG MAKE_REG(0,0,0)
#define AIC3262_RESET_REG MAKE_REG(0,0,1)
#define AIC3262_REV_PG_ID MAKE_REG(0,0,2)
#define AIC3262_REV_MASK (0b01110000)
#define AIC3262_REV_SHIFT 4
#define AIC3262_PG_MASK (0b00000111)
#define AIC3262_PG_SHIFT 0
#define AIC3262_DAC_ADC_CLKIN_REG MAKE_REG(0,0,4)
#define AIC3262_PLL_CLKIN_REG MAKE_REG(0,0,5)
#define AIC3262_PLL_CLKIN_MASK (0b00111100)
#define AIC3262_PLL_CLKIN_SHIFT 2
#define AIC3262_PLL_CLKIN_MCLK1 0
#define AIC3262_PLL_CLKIN_BCLK1 1
#define AIC3262_PLL_CLKIN_GPIO1 2
#define AIC3262_PLL_CLKIN_DIN1 3
#define AIC3262_PLL_CLKIN_BCLK2 4
#define AIC3262_PLL_CLKIN_GPI1 5
#define AIC3262_PLL_CLKIN_HF_REF_CLK 6
#define AIC3262_PLL_CLKIN_GPIO2 7
#define AIC3262_PLL_CLKIN_GPI2 8
#define AIC3262_PLL_CLKIN_MCLK2 9
#define AIC3262_CLK_VAL_MASK 0x7f
#define AIC3262_PLL_CLK_RANGE_REG MAKE_REG(0,0,5)
#define AIC3262_PLL_PR_POW_REG MAKE_REG(0,0,6)
#define AIC3262_PLL_PVAL_MASK 0x70
#define AIC3262_PLL_RVAL_MASK 0x0F
#define AIC3262_ENABLE_CLK_MASK 0x80
#define AIC3262_ENABLE_CLK 0x80
#define AIC3262_PLL_J_REG MAKE_REG(0,0,7)
#define AIC3262_JVAL_MASK 0x3f
#define AIC3262_PLL_D_MSB MAKE_REG(0,0,8)
#define AIC3262_DVAL_MSB_MASK 0xf
#define AIC3262_DVAL_LSB_MASK 0xff
#define AIC3262_PLL_D_LSB MAKE_REG(0,0,9)
#define AIC3262_PLL_CKIN_DIV MAKE_REG(0,0,10)
#define AIC3262_NDAC_DIV_POW_REG MAKE_REG(0,0,11)
#define AIC3262_MDAC_DIV_POW_REG MAKE_REG(0,0,12)
#define AIC3262_DOSR_MSB_REG MAKE_REG(0,0,13)
#define AIC3262_DOSR_MSB_MASK 0x3
#define AIC3262_DOSR_LSB_REG MAKE_REG(0,0,14)
#define AIC3262_DOSR_LSB_MASK 0xFF
#define AIC3262_NADC_DIV_POW_REG MAKE_REG(0,0,18)
#define AIC3262_MADC_DIV_POW_REG MAKE_REG(0,0,19)
#define AIC3262_AOSR_REG MAKE_REG(0,0,20)
#define AIC3262_CLKOUT_MUX MAKE_REG(0,0,21)
#define AIC3262_CLKOUT_MDIV_VAL MAKE_REG(0,0,22)
#define AIC3262_TIMER_REG MAKE_REG(0,0,23)
#define AIC3262_LF_CLK_CNTL MAKE_REG(0,0,24)
#define AIC3262_HF_CLK_CNTL_R1 MAKE_REG(0,0,25)
#define AIC3262_HF_CLK_CNTL_R2 MAKE_REG(0,0,26)
#define AIC3262_HF_CLK_CNTL_R3 MAKE_REG(0,0,27)
#define AIC3262_HF_CLK_CNTL_R4 MAKE_REG(0,0,28)
#define AIC3262_HF_CLK_TRIM_R1 MAKE_REG(0,0,29)
#define AIC3262_HF_CLK_TRIM_R2 MAKE_REG(0,0,30)
#define AIC3262_HF_CLK_TRIM_R3 MAKE_REG(0,0,31)
#define AIC3262_HF_CLK_TRIM_R4 MAKE_REG(0,0,32)
#define AIC3262_LDAC_POWER_MASK 0x80
#define AIC3262_RDAC_POWER_MASK 0x08
#define AIC3262_DAC_FLAG MAKE_REG(0,0,37)
#define AIC3262_ADC_FLAG MAKE_REG(0,0,36)
#define AIC3262_JACK_WITH_STEREO_HS (0b00000010)
#define AIC3262_JACK_WITH_MIC (0b00110000)
#define AIC3262_HEADSET_NOT_INSERTED (0b00000011)
#define AIC3262_INT_STICKY_FLAG1 MAKE_REG(0,0,42)
#define AIC3262_LEFT_DAC_OVERFLOW_INT 0x80
#define AIC3262_RIGHT_DAC_OVERFLOW_INT 0x40
#define AIC3262_MINIDSP_D_BARREL_SHIFT_OVERFLOW_INT 0x20
#define AIC3262_LEFT_ADC_OVERFLOW_INT 0x08
#define AIC3262_RIGHT_ADC_OVERFLOW_INT 0x04
#define AIC3262_MINIDSP_A_BARREL_SHIFT_OVERFLOW_INT 0x02
#define AIC3262_INT_STICKY_FLAG2 MAKE_REG(0,0,44)
#define AIC3262_LEFT_OUTPUT_DRIVER_OVERCURRENT_INT 0x80
#define AIC3262_RIGHT_OUTPUT_DRIVER_OVERCURRENT_INT 0x40
#define AIC3262_BUTTON_PRESS_INT 0x20
#define AIC3262_HEADSET_PLUG_UNPLUG_INT 0x10
#define AIC3262_LEFT_DRC_THRES_INT 0x08
#define AIC3262_RIGHT_DRC_THRES_INT 0x04
#define AIC3262_MINIDSP_D_STD_INT 0x02
#define AIC3262_RIGHT_DRC_AUX_INT 0x01
#define AIC3262_INT_STICKY_FLAG3 MAKE_REG(0,0,45)
#define AIC3262_SPK_OVER_CURRENT_INT 0x80
#define AIC3262_LEFT_AGC_NOISE_INT 0x40
#define AIC3262_RIGHT_AGC_NOISE_INT 0x20
#define AIC3262_INT1_CNTL MAKE_REG(0,0,48)
#define AIC3262_HEADSET_IN_MASK 0x80
#define AIC3262_BUTTON_PRESS_MASK 0x40
#define AIC3262_DAC_DRC_THRES_MASK 0x20
#define AIC3262_AGC_NOISE_MASK 0x10
#define AIC3262_OVER_CURRENT_MASK 0x08
#define AIC3262_OVERFLOW_MASK 0x04
#define AIC3262_SPK_OVERCURRENT_MASK 0x02
#define AIC3262_INT2_CNTL MAKE_REG(0,0,49)
#define AIC3262_INT_FMT MAKE_REG(0,0,51)
#define AIC3262_DAC_PRB MAKE_REG(0,0,60)
#define AIC3262_ADC_PRB MAKE_REG(0,0,61)
#define AIC3262_PASI_DAC_DP_SETUP MAKE_REG(0,0,63)
#define AIC3262_DAC_MVOL_CONF MAKE_REG(0,0,64)
#define AIC3262_DAC_LR_MUTE_MASK 0xc
#define AIC3262_DAC_LR_MUTE 0xc
#define AIC3262_DAC_LVOL MAKE_REG(0,0,65)
#define AIC3262_DAC_RVOL MAKE_REG(0,0,66)
#define AIC3262_HP_DETECT MAKE_REG(0,0,67)
#define AIC3262_DRC_CNTL_R1 MAKE_REG(0,0,68)
#define AIC3262_DRC_CNTL_R2 MAKE_REG(0,0,69)
#define AIC3262_DRC_CNTL_R3 MAKE_REG(0,0,70)
#define AIC3262_BEEP_CNTL_R1 MAKE_REG(0,0,71)
#define AIC3262_BEEP_CNTL_R2 MAKE_REG(0,0,72)
#define AIC3262_ADC_CHANNEL_POW MAKE_REG(0,0,81)
#define AIC3262_ADC_FINE_GAIN MAKE_REG(0,0,82)
#define AIC3262_LADC_VOL MAKE_REG(0,0,83)
#define AIC3262_RADC_VOL MAKE_REG(0,0,84)
#define AIC3262_ADC_PHASE MAKE_REG(0,0,85)
#define AIC3262_LAGC_CNTL MAKE_REG(0,0,86)
#define AIC3262_LAGC_CNTL_R2 MAKE_REG(0,0,87)
#define AIC3262_LAGC_CNTL_R3 MAKE_REG(0,0,88)
#define AIC3262_LAGC_CNTL_R4 MAKE_REG(0,0,89)
#define AIC3262_LAGC_CNTL_R5 MAKE_REG(0,0,90)
#define AIC3262_LAGC_CNTL_R6 MAKE_REG(0,0,91)
#define AIC3262_LAGC_CNTL_R7 MAKE_REG(0,0,92)
#define AIC3262_LAGC_CNTL_R8 MAKE_REG(0,0,93)
#define AIC3262_RAGC_CNTL MAKE_REG(0,0,94)
#define AIC3262_RAGC_CNTL_R2 MAKE_REG(0,0,95)
#define AIC3262_RAGC_CNTL_R3 MAKE_REG(0,0,96)
#define AIC3262_RAGC_CNTL_R4 MAKE_REG(0,0,97)
#define AIC3262_RAGC_CNTL_R5 MAKE_REG(0,0,98)
#define AIC3262_RAGC_CNTL_R6 MAKE_REG(0,0,99)
#define AIC3262_RAGC_CNTL_R7 MAKE_REG(0,0,100)
#define AIC3262_RAGC_CNTL_R8 MAKE_REG(0,0,101)
#define AIC3262_MINIDSP_ACCESS_CTRL MAKE_REG(0,0,121)
/* ****************** Page 1 Registers **************************************/
#define AIC3262_PAGE_1 128
#define AIC3262_POWER_CONF MAKE_REG(0,1, 1)
#define AIC3262_AVDD_TO_DVDD_MASK (0b00001000)
#define AIC3262_AVDD_TO_DVDD 0x8
#define AIC3262_EXT_ANALOG_SUPPLY_MASK (0b00000100)
#define AIC3262_EXT_ANALOG_SUPPLY_OFF 0x4
#define AIC3262_LDAC_PTM MAKE_REG(0,1, 3)
#define AIC3262_RDAC_PTM MAKE_REG(0,1, 4)
#define AIC3262_CM_REG MAKE_REG(0,1, 8)
#define AIC3262_HP_CTL MAKE_REG(0,1, 9)
#define AIC3262_HP_DEPOP MAKE_REG(0,1, 11)
#define AIC3262_RECV_DEPOP MAKE_REG(0,1, 12)
#define AIC3262_MA_CNTL MAKE_REG(0,1, 17)
#define AIC3262_LADC_PGA_MAL_VOL MAKE_REG(0,1, 18)
#define AIC3262_RADC_PGA_MAR_VOL MAKE_REG(0,1, 19)
#define AIC3262_LINE_AMP_CNTL_R1 MAKE_REG(0,1, 22)
#define AIC3262_LINE_AMP_CNTL_R2 MAKE_REG(0,1, 23)
#define AIC3262_HP_AMP_CNTL_R1 MAKE_REG(0,1, 27)
#define AIC3262_HP_AMP_CNTL_R2 MAKE_REG(0,1, 28)
#define AIC3262_HP_AMP_CNTL_R3 MAKE_REG(0,1, 29)
#define AIC3262_HPL_VOL MAKE_REG(0,1, 31)
#define AIC3262_HPR_VOL MAKE_REG(0,1, 32)
#define AIC3262_INT1_SEL_L MAKE_REG(0,1, 34)
#define AIC3262_CHARGE_PUMP_CNTL MAKE_REG(0,1, 35)
#define AIC3262_RAMP_CNTL_R1 MAKE_REG(0,1, 36)
#define AIC3262_RAMP_CNTL_R2 MAKE_REG(0,1, 37)
#define AIC3262_IN1L_SEL_RM MAKE_REG(0,1, 38)
#define AIC3262_IN1R_SEL_RM MAKE_REG(0,1, 39)
#define AIC3262_REC_AMP_CNTL_R5 MAKE_REG(0,1, 40)
#define AIC3262_RAMPR_VOL MAKE_REG(0,1, 41)
#define AIC3262_RAMP_TIME_CNTL MAKE_REG(0,1, 42)
#define AIC3262_SPK_AMP_CNTL_R1 MAKE_REG(0,1, 45)
#define AIC3262_SPK_AMP_CNTL_R2 MAKE_REG(0,1, 46)
#define AIC3262_SPK_AMP_CNTL_R3 MAKE_REG(0,1, 47)
#define AIC3262_SPK_AMP_CNTL_R4 MAKE_REG(0,1, 48)
#define AIC3262_MIC_BIAS_CNTL MAKE_REG(0,1, 51)
#define AIC3262_LMIC_PGA_PIN MAKE_REG(0,1, 52)
#define AIC3262_LMIC_PGA_PM_IN4 MAKE_REG(0,1, 53)
#define AIC3262_LMIC_PGA_MIN MAKE_REG(0,1, 54)
#define AIC3262_RMIC_PGA_PIN MAKE_REG(0,1, 55)
#define AIC3262_RMIC_PGA_PM_IN4 MAKE_REG(0,1, 56)
#define AIC3262_RMIC_PGA_MIN MAKE_REG(0,1, 57)
#define AIC3262_HP_FLAG MAKE_REG(0,1,66)
#define AIC3262_SPKL_POWER_MASK 0x2
#define AIC3262_SPKR_POWER_MASK 0x1
#define AIC3262_HPL_POWER_MASK 0x20
#define AIC3262_HPR_POWER_MASK 0x10
/* MIC PGA Gain Registers */
#define AIC3262_MICL_PGA MAKE_REG(0,1, 59)
#define AIC3262_MICR_PGA MAKE_REG(0,1, 60)
#define AIC3262_HEADSET_TUNING1_REG MAKE_REG(0,1, 119)
#define AIC3262_HEADSET_DETECTOR_PULSE_MASK (0b11000000)
#define AIC3262_HEADSET_DETECTOR_PULSE_RESET (0B10000000)
#define AIC3262_MIC_PWR_DLY MAKE_REG(0,1, 121)
#define AIC3262_REF_PWR_DLY MAKE_REG(0,1, 122)
#define AIC3262_CHIP_REF_PWR_ON_MASK 0x4
#define AIC3262_CHIP_REF_PWR_ON 0x4
/* ****************** Page 4 Registers **************************************/
#define AIC3262_PAGE_4 512
#define AIC3262_ASI1_BUS_FMT MAKE_REG(0,4, 1)
#define AIC3262_ASI_SELECTION_MASK (0b1100000)
#define AIC3262_ASI_DATA_WORD_LENGTH_MASK (0b0011000)
#define AIC3262_ASI_BCLK_N_MASK (0b01111111)
#define AIC3262_ASI1_LCH_OFFSET MAKE_REG(0,4, 2)
#define AIC3262_ASI1_RCH_OFFSET MAKE_REG(0,4, 3)
#define AIC3262_ASI1_CHNL_SETUP MAKE_REG(0,4, 4)
#define AIC3262_ASI1_MULTI_CH_SETUP_R1 MAKE_REG(0,4, 5)
#define AIC3262_ASI1_MULTI_CH_SETUP_R2 MAKE_REG(0,4, 6)
#define AIC3262_ASI1_ADC_INPUT_CNTL MAKE_REG(0,4, 7)
#define AIC3262_ASI1_DAC_OUT_CNTL MAKE_REG(0,4, 8)
#define AIC3262_ASI1_ADC_OUT_TRISTATE MAKE_REG(0,4, 9)
#define AIC3262_ASI1_BWCLK_CNTL_REG MAKE_REG(0,4, 10)
#define AIC3262_ASI1_BCLK_N_CNTL MAKE_REG(0,4, 11)
#define AIC3262_ASI1_BCLK_N MAKE_REG(0,4, 12)
#define AIC3262_ASI1_WCLK_N MAKE_REG(0,4, 13)
#define AIC3262_ASI1_BWCLK_OUT_CNTL MAKE_REG(0,4, 14)
#define AIC3262_ASI1_DOUT_CNTL MAKE_REG(0,4, 15)
#define AIC3262_ASI2_BUS_FMT MAKE_REG(0,4, 17)
#define AIC3262_ASI2_LCH_OFFSET MAKE_REG(0,4, 18)
#define AIC3262_ASI2_ADC_INPUT_CNTL MAKE_REG(0,4, 23)
#define AIC3262_ASI2_DAC_OUT_CNTL MAKE_REG(0,4, 24)
#define AIC3262_ASI2_BWCLK_CNTL_REG MAKE_REG(0,4, 26)
#define AIC3262_ASI2_BCLK_N_CNTL MAKE_REG(0,4, 27)
#define AIC3262_ASI2_BCLK_N MAKE_REG(0,4, 28)
#define AIC3262_ASI2_WCLK_N MAKE_REG(0,4, 29)
#define AIC3262_ASI2_BWCLK_OUT_CNTL MAKE_REG(0,4, 30)
#define AIC3262_ASI2_DOUT_CNTL MAKE_REG(0,4, 31)
#define AIC3262_ASI3_BUS_FMT MAKE_REG(0,4, 33)
#define AIC3262_ASI3_LCH_OFFSET MAKE_REG(0,4, 34)
#define AIC3262_ASI3_ADC_INPUT_CNTL MAKE_REG(0,4, 39)
#define AIC3262_ASI3_DAC_OUT_CNTL MAKE_REG(0,4, 40)
#define AIC3262_ASI3_BWCLK_CNTL_REG MAKE_REG(0,4, 42)
#define AIC3262_ASI3_BCLK_N_CNTL MAKE_REG(0,4, 43)
#define AIC3262_ASI3_BCLK_N MAKE_REG(0,4, 44)
#define AIC3262_ASI3_WCLK_N MAKE_REG(0,4, 45)
#define AIC3262_ASI3_BWCLK_OUT_CNTL MAKE_REG(0,4, 46)
#define AIC3262_ASI3_DOUT_CNTL MAKE_REG(0,4, 47)
#define AIC3262_DMIC_INPUT_CNTL MAKE_REG(0,4, 101)
#define AIC3262_GPIO1_IO_CNTL MAKE_REG(0,4, 86)
#define AIC3262_GPIO_D6_D2 (0b01111100)
#define AIC3262_GPIO_D2_SHIFT (2)
#define AIC3262_GPIO_D1_SHIFT (1)
#define AIC3262_GPIO_D4_SHIFT (4)
#define AIC3262_GPIO2_IO_CNTL MAKE_REG(0,4, 87)
#define AIC3262_GPI1_EN MAKE_REG(0,4, 91)
#define AIC3262_GPI1_D2_D1 (0b00000110)
#define AIC3262_GPI2_D5_D4 (0b00110000)
#define AIC3262_GPI2_EN MAKE_REG(0, 4, 92)
#define AIC3262_GPO1_OUT_CNTL MAKE_REG(0, 4, 96)
#define AIC3262_GPO1_D4_D1 (0b00011110)
#define AIC3262_DMIC_INPUT_CONTROL MAKE_REG(0, 4, 101)
#define AIC3262_DMIC_CONFIGURE_MASK (0b00011111)
#define AIC3262_DMIC_CONFIGURE_SHIFT (0)
#define AIC3262_MINIDSP_DATA_PORT_CNTL MAKE_REG(0, 4, 118)
#define AIC3262_DAC_ASI_LR_UNMUTE_MASK 0x50
#define AIC3262_DAC_ASI_LR_UNMUTE 0x50
#define AIC3262_WCLK_BCLK_MASTER_MASK (0b00100110)
#define AIC3262_WCLK_MASTER_MASK (0b00100000)
#define AIC3262_BCLK_MASTER_MASK (0b00000100)
#define AIC3262_BCLK_OFFSET_MASK (0b11111111)
#define AIC3262_ASI_INTERFACE_MASK (0b11100000)
#define AIC3262_WCLK_OUT_MASK (0b00100000)
#define AIC3262_BCLK_OUT_MASK (0b00000100)
#define AIC3262_BCLK_INV_MASK (0b00000010)
#define AIC3262_ADC_ADAPTIVE_CRAM_REG MAKE_REG(40,0,1)
#define AIC3262_DAC_ADAPTIVE_BANK1_REG MAKE_REG(80,0,1)
#define AIC3262_DAC_ADAPTIVE_BANK2_REG MAKE_REG(82,0,1)
#define AIC3262_ADC_DATAPATH_SETUP MAKE_REG(0,0,81)
#define AIC3262_DAC_DATAPATH_SETUP MAKE_REG(0,0,63)
#endif

View File

@@ -1,408 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include "aic3xxx_cfw.h"
#include "aic3xxx_cfw_ops.h"
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/mfd/tlv320aic3262-core.h>
#include <linux/mfd/tlv320aic3262-registers.h>
#include "tlv320aic326x.h"
#include <sound/soc.h>
#include "aic3262_codec_ops.h"
#define DSP_STATUS(rs,adc_dac,rpos,rspos) rs |= ( ((adc_dac>>rpos) & 1) << rspos)
int aic3262_ops_reg_read(void *p,unsigned int reg)
{
struct aic3262_priv *ps = p;
cfw_register *c = (cfw_register *) &reg;
aic326x_reg_union mreg;
mreg.aic326x_register.offset = c->offset;
mreg.aic326x_register.page = c->page;
mreg.aic326x_register.book = c->book;
mreg.aic326x_register.reserved = 0;
return aic3262_reg_read(ps->codec->control_data,
mreg.aic326x_register_int);
}
int aic3262_ops_reg_write(void *p,unsigned int reg,unsigned char mval)
{
struct aic3262_priv *ps = p;
aic326x_reg_union mreg;
cfw_register *c = (cfw_register *) &reg;
mreg.aic326x_register.offset = c->offset;
mreg.aic326x_register.page = c->page;
mreg.aic326x_register.book = c->book;
mreg.aic326x_register.reserved = 0;
mval = c->data;
DBG("reg_write:page %d book %d offset %d mval : %#x\n",mreg.aic326x_register.page,mreg.aic326x_register.book,mreg.aic326x_register.offset,mval);
return aic3262_reg_write(ps->codec->control_data, mreg.aic326x_register_int, mval);
}
int aic3262_ops_set_bits(void *p,unsigned int reg,
unsigned char mask, unsigned char val)
{
struct aic3262_priv *ps = p;
aic326x_reg_union mreg;
cfw_register *c = (cfw_register *) &reg;
mreg.aic326x_register.offset = c->offset;
mreg.aic326x_register.page = c->page;
mreg.aic326x_register.book = c->book;
mreg.aic326x_register.reserved = 0;
DBG("set_bits:page %d book %d offset %d mask %#x val %#x\n",mreg.aic326x_register.page,mreg.aic326x_register.book,mreg.aic326x_register.offset,mask,val);
return aic3262_set_bits(ps->codec->control_data,mreg.aic326x_register_int,mask,val);
}
int aic3262_ops_bulk_read(void *p,unsigned int reg,int count, u8 *buf)
{
struct aic3262_priv *ps = p;
aic326x_reg_union mreg;
cfw_register *c = (cfw_register *) &reg;
mreg.aic326x_register.offset = c->offset;
mreg.aic326x_register.page = c->page;
mreg.aic326x_register.book = c->book;
mreg.aic326x_register.reserved = 0;
return aic3262_bulk_read(ps->codec->control_data,mreg.aic326x_register_int,count,buf);
}
int aic3262_ops_bulk_write(void *p,unsigned int reg ,int count, const u8 *buf)
{
struct aic3262_priv *ps = p;
aic326x_reg_union mreg;
cfw_register *c = (cfw_register *) &reg;
mreg.aic326x_register.offset = c->offset;
mreg.aic326x_register.page = c->page;
mreg.aic326x_register.book = c->book;
mreg.aic326x_register.reserved = 0;
DBG("bulk_write: ncmd %d page %d book %d offset %d data[0] %d\n",count,mreg.aic326x_register.page,mreg.aic326x_register.book,mreg.aic326x_register.offset,buf[0]);
aic3262_bulk_write(ps->codec->control_data,mreg.aic326x_register_int,count,buf);
return 0;
}
/*****************************************************************************
Function Name : aic3262_ops_dlock_lock
Argument : pointer argument to the codec
Return value : Integer
Purpose : To Read the run state of the DAC and ADC
by reading the codec and returning the run state
Run state Bit format
------------------------------------------------------
D31|..........| D7 | D6| D5 | D4 | D3 | D2 | D1 | D0 |
R R R LADC RADC R R LDAC RDAC
------------------------------------------------------
*******************************************************************************/
int aic3262_ops_lock(void *pv)
{
int run_state=0;
struct aic3262_priv *aic3262 = (struct aic3262_priv *) pv;
mutex_lock(&aic3262->codec->mutex);
/* Reading the run state of adc and dac */
run_state = get_runstate(aic3262->codec->control_data);
return run_state;
}
/********************************************************************************
Function name : aic3262_ops_dlock_unlock
Argument : pointer argument to the codec
Return Value : integer returning 0
Purpose : To unlock the mutex acqiured for reading
run state of the codec
*********************************************************************************/
int aic3262_ops_unlock(void *pv)
{
/*Releasing the lock of mutex */
struct aic3262_priv *aic3262 = (struct aic3262_priv *) pv;
mutex_unlock(&aic3262->codec->mutex);
return 0;
}
/*********************************************************************************
Function Name : aic3262_ops_dlock_stop
Argument : pointer Argument to the codec
mask tells us the bit format of the
codec running state
Bit Format:
------------------------------------------------------
D31|..........| D7 | D6| D5 | D4 | D3 | D2 | D1 | D0 |
R R R AL AR R R DL DR
------------------------------------------------------
R - Reserved
A - minidsp_A
D - minidsp_D
***********************************************************************************/
int aic3262_ops_stop (void *pv, int mask)
{
int run_state=0;
int cur_state=0;
int count = 100;
struct aic3262_priv *aic3262 = (struct aic3262_priv *) pv;
int limask=0;
mutex_lock(&aic3262->codec->mutex);
run_state = get_runstate(aic3262->codec->control_data);
if ( ( limask=(mask & AIC3XX_COPS_MDSP_A) ) )
{
if((limask & 0x30) == 0x30) //Both ADC's needs to switchoff
aic3262_set_bits(aic3262->codec->control_data,AIC3262_ADC_DATAPATH_SETUP,0xC0,0);
else
{
if(limask & 0x10) //Right ADC is on, we need to switchoff
aic3262_set_bits(aic3262->codec->control_data,AIC3262_ADC_DATAPATH_SETUP,0x40,0);
if(limask & 0x20) // Left ADC is on , we need to switchoff
aic3262_set_bits(aic3262->codec->control_data,AIC3262_ADC_DATAPATH_SETUP,0x80,0);
}
}
if( ( limask= (mask & AIC3XX_COPS_MDSP_D) ) )
{
if( (limask & 0x03)== 0x03 )
{
aic3262_set_bits(aic3262->codec->control_data,AIC3262_DAC_DATAPATH_SETUP,0xC0,0);
}
else
{
if(limask & 0x01)
aic3262_set_bits(aic3262->codec->control_data,AIC3262_DAC_DATAPATH_SETUP,0x40,0);
if(limask & 0x02)
aic3262_set_bits(aic3262->codec->control_data,AIC3262_DAC_DATAPATH_SETUP,0x80,0);
}
}
// waiting for write to complete
do
{
cur_state = get_runstate(aic3262->codec->control_data);
count--;
}while( ( (cur_state&mask&AIC3XX_COPS_MDSP_A) || (cur_state&mask&AIC3XX_COPS_MDSP_D) ) && count );
return run_state;
}
/*****************************************************************************
Function name : aic3262_ops_dlock_restore
Argument : pointer argument to the codec,run_state
Return Value : integer returning 0
Purpose : To unlock the mutex acqiured for reading
run state of the codec and to restore the states of the dsp
*******************************************************************************/
int aic3262_ops_restore(void *pv, int run_state)
{
int sync_state = 0;
int li_cur_state = 0;
struct aic3262_priv *aic3262 = (struct aic3262_priv *)pv;
/* This is for read the sync mode register state */
sync_state = SYNC_STATE(aic3262);
/* Reading the current dsp state */
li_cur_state = get_runstate(aic3262->codec->control_data);
//checking whether the sync mode has been set or not and checking the current state
if( ((run_state & 0x30) && (run_state & 0x03)) && (sync_state & 0x80) )
aic3262_restart_dsps_sync(pv,run_state);
else
aic3262_dsp_pwrup(pv,run_state);
mutex_unlock(&aic3262->codec->mutex);
return 0;
}
/*****************************************************************************
Function name : aic3262_ops_adaptivebuffer_swap
Argument : pointer argument to the codec,mask tells us which dsp has to
be chosen for swapping
Return Value : integer returning 0
Purpose : To swap the coefficient buffers of minidsp according to mask
*******************************************************************************/
int aic3262_ops_adaptivebuffer_swap(void *pv,int mask)
{
int read_state=0;
struct aic3262_priv *aic3262 = (struct aic3262_priv *) pv;
if(mask & AIC3XX_ABUF_MDSP_A)
{
int count=0;
aic3262_set_bits(aic3262->codec->control_data,AIC3262_ADC_ADAPTIVE_CRAM_REG,0x1,0x1);
do
{
read_state = aic3262_reg_read(aic3262->codec->control_data,AIC3262_ADC_ADAPTIVE_CRAM_REG);
count++;
}while( (read_state & 0x1) && (count <= 60) );
}
if(mask & AIC3XX_ABUF_MDSP_D1)
{
int count=0;
aic3262_set_bits(aic3262->codec->control_data,AIC3262_DAC_ADAPTIVE_BANK1_REG,0x1,0x1);
do
{
read_state = aic3262_reg_read(aic3262->codec->control_data, AIC3262_DAC_ADAPTIVE_BANK1_REG );
count++;
}while( (read_state & 0x1) && (count <= 60) );
}
if(mask & AIC3XX_ABUF_MDSP_D2)
{
int count=0;
aic3262_set_bits(aic3262->codec->control_data,AIC3262_DAC_ADAPTIVE_BANK2_REG,0x1,0x1);
do
{
read_state = aic3262_reg_read(aic3262->codec->control_data,AIC3262_DAC_ADAPTIVE_BANK2_REG);
count++;
}while( (read_state & 0x1) && (count <= 60) );
}
return 0;
}
/*****************************************************************************
Function name : get_runstate
Argument : pointer argument to the codec
Return Value : integer returning the runstate
Purpose : To read the current state of the dac's and adc's
*******************************************************************************/
int get_runstate(void *ps)
{
struct aic3262 *pr = ps;
int run_state=0;
int DAC_state=0,ADC_state=0;
/* Read the run state */
DAC_state = aic3262_reg_read(pr,AIC3262_DAC_FLAG);
ADC_state = aic3262_reg_read(pr,AIC3262_ADC_FLAG);
DSP_STATUS(run_state,ADC_state,6,5);
DSP_STATUS(run_state,ADC_state,2,4);
DSP_STATUS(run_state,DAC_state,7,1);
DSP_STATUS(run_state,DAC_state,3,0);
return run_state;
}
/*****************************************************************************
Function name : aic3262_dsp_pwrdwn_status
Argument : pointer argument to the codec , cur_state of dac's and adc's
Return Value : integer returning 0
Purpose : To read the status of dsp's
*******************************************************************************/
int aic3262_dsp_pwrdwn_status(
void *pv //ptr to the priv data structure
)
{
struct aic3262_priv *aic3262 = pv;
int count = 100;
int cur_state = 0;
aic3262_set_bits(aic3262->codec->control_data,AIC3262_ADC_DATAPATH_SETUP,0XC0,0);
aic3262_set_bits(aic3262->codec->control_data,AIC3262_DAC_DATAPATH_SETUP,0XC0,0);
do
{
cur_state = get_runstate(aic3262->codec->control_data);
}while(cur_state && count--);
return 0;
}
int aic3262_dsp_pwrup(void *pv,int state)
{
int cur_state = 0;
int count =100;
struct aic3262_priv *aic3262 = (struct aic3262_priv *)pv;
if(state & AIC3262_COPS_MDSP_A)
aic3262_set_bits(aic3262->codec->control_data,AIC3262_ADC_DATAPATH_SETUP,0XC0,0xC0);
else
{
if(state & AIC3262_COPS_MDSP_A_L)
aic3262_set_bits(aic3262->codec->control_data,AIC3262_ADC_DATAPATH_SETUP,0x80,0x80);
if(state & AIC3262_COPS_MDSP_A_R)
aic3262_set_bits(aic3262->codec->control_data,AIC3262_ADC_DATAPATH_SETUP,0x40,0x40);
}
if(state & AIC3262_COPS_MDSP_D)
aic3262_set_bits(aic3262->codec->control_data,AIC3262_DAC_DATAPATH_SETUP,0XC0,0xC0);
else
{
if(state & AIC3262_COPS_MDSP_D_L)
aic3262_set_bits(aic3262->codec->control_data,AIC3262_DAC_DATAPATH_SETUP,0x80,0x80);
if(state & AIC3262_COPS_MDSP_D_R)
aic3262_set_bits(aic3262->codec->control_data,AIC3262_DAC_DATAPATH_SETUP,0x40,0x40);
}
//loop for waiting for the dsps to power up together
do
{
cur_state = get_runstate(aic3262->codec->control_data);
}while ((state == cur_state ) && count--);
return 0;
}
int aic3262_restart_dsps_sync(void *pv,int run_state)
{
aic3262_dsp_pwrdwn_status(pv);
//specific command sequence to be added later
/*
....................
....................
....................
*/
aic3262_dsp_pwrup(pv,run_state);
//specific commands to be added later
/*
....................
....................
....................
*/
return 0;
}
const aic3xxx_codec_ops aic3262_cfw_codec_ops = {
.reg_read = aic3262_ops_reg_read,
.reg_write = aic3262_ops_reg_write,
.set_bits = aic3262_ops_set_bits,
.bulk_read = aic3262_ops_bulk_read,
.bulk_write = aic3262_ops_bulk_write,
.lock = aic3262_ops_lock,
.unlock = aic3262_ops_unlock,
.stop = aic3262_ops_stop ,
.restore = aic3262_ops_restore,
.bswap = aic3262_ops_adaptivebuffer_swap,
};

View File

@@ -1,43 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#define SYNC_STATE(p) aic3262_reg_read(p->codec->control_data,AIC3262_DAC_PRB)
#define AIC3262_COPS_MDSP_A 0x30
#define AIC3262_COPS_MDSP_A_L 0x20
#define AIC3262_COPS_MDSP_A_R 0x10
#define AIC3262_COPS_MDSP_D 0x03
#define AIC3262_COPS_MDSP_D_L 0x02
#define AIC3262_COPS_MDSP_D_R 0x01
int get_runstate(void *);
int aic3262_dsp_pwrup(void *,int);
int aic3262_pwr_down(void *,int ,int ,int ,int);
int aic3262_dsp_pwrdwn_status(void *);
int aic3262_ops_reg_read(void *p,unsigned int reg);
int aic3262_ops_reg_write(void *p,unsigned int reg,unsigned char mval);
int aic3262_ops_set_bits(void *p,unsigned int reg,unsigned char mask, unsigned char val);
int aic3262_ops_bulk_read(void *p,unsigned int reg,int count, u8 *buf);
int aic3262_ops_bulk_write(void *p, unsigned int reg,int count, const u8 *buf);
int aic3262_ops_lock(void *pv);
int aic3262_ops_unlock(void *pv);
int aic3262_ops_stop (void *pv, int mask);
int aic3262_ops_restore(void *pv, int run_state);
int aic3262_ops_adaptivebuffer_swap(void *pv,int mask);
int aic3262_restart_dsps_sync(void *pv,int run_state);

View File

@@ -1,349 +0,0 @@
/*
* linux/sound/soc/codecs/AIC3262_tiload.c
*
*
* Copyright (C) 2010 Texas Instruments, Inc.
*
*
*
* This package 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.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* History:
*
* Rev 0.1 Tiload support TI 16-09-2010
*
* The Tiload programming support is added to AIC3262.
*
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <sound/soc.h>
#include <sound/control.h>
#include <linux/switch.h>
#include <sound/jack.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/mfd/tlv320aic3262-core.h>
#include "tlv320aic326x.h"
#include "aic326x_tiload.h"
/* enable debug prints in the driver */
//#define DEBUG
#undef DEBUG
#ifdef DEBUG
#define dprintk(x...) printk(x)
#else
#define dprintk(x...)
#endif
#ifdef AIC3262_TiLoad
/* Function prototypes */
#ifdef REG_DUMP_aic3262
static void aic3262_dump_page(struct i2c_client *i2c, u8 page);
#endif
/* externs */
/*extern int aic3262_change_page(struct snd_soc_codec *codec, u8 new_page);
extern int aic3262_change_book(struct snd_soc_codec *codec, u8 new_book);*/
extern int aic3262_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value);
int aic3262_driver_init(struct snd_soc_codec *codec);
/************** Dynamic aic3262 driver, TI LOAD support ***************/
static struct cdev *aic3262_cdev;
static aic326x_reg_union aic_reg;
static int aic3262_major = 0; /* Dynamic allocation of Mjr No. */
static int aic3262_opened = 0; /* Dynamic allocation of Mjr No. */
static struct snd_soc_codec *aic3262_codec;
struct class *tiload_class;
static unsigned int magic_num = 0xE0;
/******************************** Debug section *****************************/
#ifdef REG_DUMP_aic3262
/*
*----------------------------------------------------------------------------
* Function : aic3262_dump_page
* Purpose : Read and display one codec register page, for debugging purpose
*----------------------------------------------------------------------------
*/
static void aic3262_dump_page(struct i2c_client *i2c, u8 page)
{
int i;
u8 data;
u8 test_page_array[8];
dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
// aic3262_change_page(codec, page);
data = 0x0;
i2c_master_send(i2c, data, 1);
i2c_master_recv(i2c, test_page_array, 8);
dprintk("\n------- aic3262 PAGE %d DUMP --------\n", page);
for (i = 0; i < 8; i++) {
printk(" [ %d ] = 0x%x\n", i, test_page_array[i]);
}
}
#endif
/*
*----------------------------------------------------------------------------
* Function : tiload_open
*
* Purpose : open method for aic3262-tiload programming interface
*----------------------------------------------------------------------------
*/
static int tiload_open(struct inode *in, struct file *filp)
{
dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
if (aic3262_opened) {
dprintk("%s device is already opened\n", "aic3262");
dprintk("%s: only one instance of driver is allowed\n",
"aic3262");
return -1;
}
aic3262_opened++;
return 0;
}
/*
*----------------------------------------------------------------------------
* Function : tiload_release
*
* Purpose : close method for aic3262_tilaod programming interface
*----------------------------------------------------------------------------
*/
static int tiload_release(struct inode *in, struct file *filp)
{
dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
aic3262_opened--;
return 0;
}
/*
*----------------------------------------------------------------------------
* Function : tiload_read
*
* Purpose : read method for mini dsp programming interface
*----------------------------------------------------------------------------
*/
static ssize_t tiload_read(struct file *file, char __user * buf,
size_t count, loff_t * offset)
{
static char rd_data[8];
char reg_addr;
size_t size;
#ifdef DEBUG
int i;
#endif
struct aic3262 *control = aic3262_codec->control_data;
dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
if (count > 128) {
printk("Max 128 bytes can be read\n");
count = 128;
}
/* copy register address from user space */
size = copy_from_user(&reg_addr, buf, 1);
if (size != 0) {
printk("read: copy_from_user failure\n");
return -1;
}
/* Send the address to device thats is to be read */
aic_reg.aic326x_register.offset = reg_addr;
size = aic3262_bulk_read(control, aic_reg.aic326x_register_int, count, rd_data);
/*
if (i2c_master_send(i2c, &reg_addr, 1) != 1) {
dprintk("Can not write register address\n");
return -1;
}
size = i2c_master_recv(i2c, rd_data, count);
*/
#ifdef DEBUG
printk(KERN_ERR "read size = %d, reg_addr= %x , count = %d\n",
(int)size, reg_addr, (int)count);
for (i = 0; i < (int)size; i++) {
dprintk(KERN_ERR "rd_data[%d]=%x\n", i, rd_data[i]);
}
#endif
if (size != count) {
dprintk("read %d registers from the codec\n", size);
}
if (copy_to_user(buf, rd_data, size) != 0) {
dprintk("copy_to_user failed\n");
return -1;
}
return size;
}
/*
*----------------------------------------------------------------------------
* Function : tiload_write
*
* Purpose : write method for aic3262_tiload programming interface
*----------------------------------------------------------------------------
*/
static ssize_t tiload_write(struct file *file, const char __user * buf,
size_t count, loff_t * offset)
{
static char wr_data[8];
u8 pg_no;
unsigned int reg;
#ifdef DEBUG
int i;
#endif
struct aic3262 *control = aic3262_codec->control_data;
dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
/* copy buffer from user space */
if (copy_from_user(wr_data, buf, count)) {
printk("copy_from_user failure\n");
return -1;
}
#ifdef DEBUG
dprintk(KERN_ERR "write size = %d\n", (int)count);
for (i = 0; i < (int)count; i++) {
printk(KERN_INFO "\nwr_data[%d]=%x\n", i, wr_data[i]);
}
#endif
if(wr_data[0] == 0)
{
//change of page seen, but will only be registered
aic_reg.aic326x_register.page = wr_data[1];
return count;// trick
}
else
if(wr_data[0] == 127 /* && aic_reg.aic326x_register.page == 0*/)
{
//change of book seen, but will not be sent for I2C write
aic_reg.aic326x_register.book = wr_data[1];
return count; //trick
}
else
{
aic_reg.aic326x_register.offset = wr_data[0];
aic3262_bulk_write(control, aic_reg.aic326x_register_int, count - 1,&wr_data[1]);
return count;
}
/* if (wr_data[0] == 0) {
aic3262_change_page(aic3262_codec, wr_data[1]);
return count;
}
pg_no = aic3262_private->page_no;
if ((wr_data[0] == 127) && (pg_no == 0)) {
aic3262_change_book(aic3262_codec, wr_data[1]);
return count;
}
return i2c_master_send(i2c, wr_data, count);*/
}
static long tiload_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg)
{
long num = 0;
void __user *argp = (void __user *)arg;
if (_IOC_TYPE(cmd) != aic3262_IOC_MAGIC)
return -ENOTTY;
dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
switch (cmd) {
case aic3262_IOMAGICNUM_GET:
num = copy_to_user(argp, &magic_num, sizeof(int));
break;
case aic3262_IOMAGICNUM_SET:
num = copy_from_user(&magic_num, argp, sizeof(int));
break;
}
return num;
}
/*********** File operations structure for aic3262-tiload programming *************/
static struct file_operations aic3262_fops = {
.owner = THIS_MODULE,
.open = tiload_open,
.release = tiload_release,
.read = tiload_read,
.write = tiload_write,
.unlocked_ioctl = tiload_ioctl,
};
/*
*----------------------------------------------------------------------------
* Function : aic3262_driver_init
*
* Purpose : Register a char driver for dynamic aic3262-tiload programming
*----------------------------------------------------------------------------
*/
int aic3262_driver_init(struct snd_soc_codec *codec)
{
int result;
dev_t dev = MKDEV(aic3262_major, 0);
dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
aic3262_codec = codec;
dprintk("allocating dynamic major number\n");
result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
if (result < 0) {
dprintk("cannot allocate major number %d\n", aic3262_major);
return result;
}
tiload_class = class_create(THIS_MODULE, DEVICE_NAME);
aic3262_major = MAJOR(dev);
dprintk("allocated Major Number: %d\n", aic3262_major);
aic3262_cdev = cdev_alloc();
cdev_init(aic3262_cdev, &aic3262_fops);
aic3262_cdev->owner = THIS_MODULE;
aic3262_cdev->ops = &aic3262_fops;
aic_reg.aic326x_register.page = 0;
aic_reg.aic326x_register.book = 0;
if (cdev_add(aic3262_cdev, dev, 1) < 0) {
dprintk("aic3262_driver: cdev_add failed \n");
unregister_chrdev_region(dev, 1);
aic3262_cdev = NULL;
return 1;
}
dprintk("Registered aic3262 TiLoad driver, Major number: %d \n",
aic3262_major);
//class_device_create(tiload_class, NULL, dev, NULL, DEVICE_NAME, 0);
return 0;
}
#endif

View File

@@ -1,36 +0,0 @@
/*
* linux/sound/soc/codecs/aic3262_tiload.h
*
*
* Copyright (C) 2011 Texas Instruments Inc.
*
*
*
* This package 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.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* History:
*
*
*
*
*/
#ifndef _AIC3262_TILOAD_H
#define _AIC3262_TILOAD_H
/* typedefs required for the included header files */
typedef char *string;
/* defines */
#define DEVICE_NAME "tiload_node"
#define aic3262_IOC_MAGIC 0xE0
#define aic3262_IOMAGICNUM_GET _IOR(aic3262_IOC_MAGIC, 1, int)
#define aic3262_IOMAGICNUM_SET _IOW(aic3262_IOC_MAGIC, 2, int)
#endif

View File

@@ -1,426 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/**
* \file Codec Firmware Declarations
*/
#ifndef CFW_FIRMWARE_H_
#define CFW_FIRMWARE_H_
/** \defgroup bt Basic Types */
/* @{ */
#ifndef AIC3XXX_CFW_HOST_BLD
#include <asm-generic/int-ll64.h>
#else
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned long int u32;
#endif
typedef signed char i8;
typedef signed short int i16;
typedef signed long int i32;
#define CFW_FW_MAGIC 0xC0D1F1ED
/* @} */
/** \defgroup pd Arbitrary Limitations */
/* @{ */
#ifndef CFW_MAX_ID
# define CFW_MAX_ID (64) ///<Max length of string identifies
#endif
#ifndef CFW_MAX_DESC
# define CFW_MAX_DESC (512) ///<Max length of description
#endif
#ifndef CFW_MAX_NOVLY
# define CFW_MAX_NOVLY (4) ///<Max number of overlays per PFW
#endif
#ifndef CFW_MAX_NCFG
# define CFW_MAX_NCFG (16) ///<Max number of configurations per PFW
#endif
#ifndef CFW_MAX_TRANSITIONS
# define CFW_MAX_TRANSITIONS (32) ///<max number of pre-defined transition
#endif
#ifndef CFW_MAX_NPFW
# define CFW_MAX_NPFW (16) ///<Max number fo process flows
#endif
#ifndef CFW_MAX_MODES
# define CFW_MAX_MODES (32) ///<Max number of modes
#endif
#ifndef CFW_MAX_ASI
# define CFW_MAX_ASI (4) ///<Max number ASIs in a single device
#endif
/* @} */
/** \defgroup st Enums, Flags, Macros and Supporting Types */
/* @{ */
/**
* Sample rate bitmask
*
*/
enum cfw_fs {
CFW_FS_8KHZ = 0x0001u,
CFW_FS_11KHZ = 0x0002u,
CFW_FS_16KHZ = 0x0004u,
CFW_FS_22KHZ = 0x0008u,
CFW_FS_24KHZ = 0x0010u,
CFW_FS_32KHZ = 0x0020u,
CFW_FS_44KHZ = 0x0040u,
CFW_FS_48KHZ = 0x0080u,
CFW_FS_88KHZ = 0x0100u,
CFW_FS_96KHZ = 0x0200u,
CFW_FS_176KHZ = 0x0400u,
CFW_FS_192KHZ = 0x0800u,
CFW_FS_ANY = 0x8000u,
CFW_FS_ALL = 0x0FFFu,
};
/**
* Sample rate index
*
*/
enum cfw_fsi {
CFW_FSI_8KHZ,
CFW_FSI_11KHZ,
CFW_FSI_16KHZ,
CFW_FSI_22KHZ,
CFW_FSI_24KHZ,
CFW_FSI_32KHZ,
CFW_FSI_44KHZ,
CFW_FSI_48KHZ,
CFW_FSI_88KHZ,
CFW_FSI_96KHZ,
CFW_FSI_176KHZ,
CFW_FSI_192KHZ,
CFW_FSI_ANY = 15,
};
/**
* Device Family Identifier
*
*/
typedef enum __attribute__ ((__packed__)) cfw_dfamily {
CFW_DFM_TYPE_A,
CFW_DFM_TYPE_B,
CFW_DFM_TYPE_C
} cfw_dfamily;
/**
* Device Identifier
*
*/
typedef enum __attribute__ ((__packed__)) cfw_device {
CFW_DEV_DAC3120,
CFW_DEV_DAC3100,
CFW_DEV_AIC3120,
CFW_DEV_AIC3100,
CFW_DEV_AIC3110,
CFW_DEV_AIC3111,
CFW_DEV_AIC36,
CFW_DEV_AIC3206,
CFW_DEV_AIC3204,
CFW_DEV_AIC3254,
CFW_DEV_AIC3256,
CFW_DEV_AIC3253,
CFW_DEV_AIC3212,
CFW_DEV_AIC3262,
CFW_DEV_AIC3017,
CFW_DEV_AIC3008,
} cfw_device;
/**
* Transition Sequence Identifier
*
*/
typedef enum cfw_transition_t {
CFW_TRN_INIT,
CFW_TRN_RESUME,
CFW_TRN_NEUTRAL,
CFW_TRN_SUSPEND,
CFW_TRN_EXIT,
CFW_TRN_N
} cfw_transition_t;
static const char * const cfw_transition_id[] = {
[CFW_TRN_INIT] "INIT",
[CFW_TRN_RESUME] "RESUME",
[CFW_TRN_NEUTRAL] "NEUTRAL",
[CFW_TRN_SUSPEND] "SUSPEND",
[CFW_TRN_EXIT] "EXIT",
};
/* @} */
/** \defgroup ds Data Structures */
/* @{ */
/**
* CFW Meta Command
* These commands do not appear in the register
* set of the device.
* Mainly delay, wait and set_bits.
*/
typedef enum __attribute__ ((__packed__)) cfw_meta_cmd {
CFW_META_DELAY = 0x80,
CFW_META_UPDTBITS,
CFW_META_WAITBITS,
CFW_META_LOCK,
} cfw_meta_cmd;
/**
* CFW Delay
* Used for the meta command delay
* Has one parameter of delay time in ms
*/
typedef struct cfw_meta_delay {
u16 delay;
cfw_meta_cmd mcmd;
u8 unused1;
} cfw_meta_delay;
/**
* CFW set_bits or wait
* Both these meta commands have same arguments
* mcmd will be used to specify which command it is
* has parameters of book, page, offset and mask
*/
typedef struct cfw_meta_bitop {
u16 unused1;
cfw_meta_cmd mcmd;
u8 mask;
} cfw_meta_bitop;
/**
* CFW meta register
* Contains the data structures for the meta commands
*/
typedef union cfw_meta_register {
struct {
u16 unused1;
cfw_meta_cmd mcmd;
u8 unused2;
};
cfw_meta_delay delay;
cfw_meta_bitop bitop;
} cfw_meta_register;
/**
* CFW Register
*
* A single reg write
*
*/
typedef union cfw_register {
struct {
u8 book;
u8 page;
u8 offset;
u8 data;
};
u32 bpod;
cfw_meta_register meta;
} cfw_register;
/**
* CFW Burst
*
* A single I2C/SPI burst write sequence
*
*/
typedef struct cfw_burst {
u32 length;
union {
cfw_register reg;
struct {
u8 bpo[3];
u8 data[1];
};
};
} cfw_burst;
/**
* CFW Command
*
* Can be a either a
* -# single register write,
* -# a burst write, or
* -# meta-command
*
*/
typedef union cfw_cmd {
cfw_register reg;
cfw_burst *burst;
} cfw_cmd;
/**
* CFW Block Type
*
* Block identifier
*
*/
typedef enum __attribute__ ((__packed__)) cfw_block_t {
CFW_BLOCK_SYSTEM_PRE,
CFW_BLOCK_A_INST,
CFW_BLOCK_A_A_COEF,
CFW_BLOCK_A_B_COEF,
CFW_BLOCK_A_F_COEF,
CFW_BLOCK_D_INST,
CFW_BLOCK_D_A1_COEF,
CFW_BLOCK_D_B1_COEF,
CFW_BLOCK_D_A2_COEF,
CFW_BLOCK_D_B2_COEF,
CFW_BLOCK_D_F_COEF,
CFW_BLOCK_SYSTEM_POST,
CFW_BLOCK_N,
CFW_BLOCK_BURSTS = 0x80
} cfw_block_t;
#define CFW_BLOCK_BURSTS(x) ((x)&CFW_BLOCK_BURSTS)
#define CFW_BLOCK_D_A_COEF CFW_BLOCK_D_A1_COEF
#define CFW_BLOCK_D_B_COEF CFW_BLOCK_D_B1_COEF
/**
* CFW Block
*
* A block of logically grouped sequences/commands/meta-commands
*
*/
typedef struct cfw_block {
cfw_block_t type;
int ncmds;
cfw_cmd cmd[1];
} cfw_block;
/**
* CFW Image
*
* A downloadable image
*/
typedef struct cfw_image {
char name[CFW_MAX_ID]; ///< Name of the pfw/overlay/configuration
char desc[CFW_MAX_DESC]; ///< User string
cfw_block *block[CFW_BLOCK_N];
} cfw_image;
/**
* Sysclk source
*
*/
typedef enum __attribute__ ((__packed__)) cfw_sclk_source {
CFW_SYSCLK_MCLK1,
CFW_SYSCLK_MCLK2,
CFW_SYSCLK_BCLK1,
CFW_SYSCLK_GPIO1,
CFW_SYSCLK_PLL_CLK,
CFW_SYSCLK_BCLK2,
CFW_SYSCLK_GPI1,
CFW_SYSCLK_HF_REF_CLK,
CFW_SYSCLK_HF_OSC_CLK,
CFW_SYSCLK_GPIO2,
CFW_SYSCLK_GPI2,
} cfw_sclk_source;
/**
* Process flow
*
* Complete description of a process flow
*/
typedef struct cfw_pfw {
char name[CFW_MAX_ID]; ///< Name of the process flow
char desc[CFW_MAX_DESC]; ///< User string
u32 version;
u16 supported_fs; ///< Sampling rates at which this process flow may run (bit mask; see \ref cfw_fs)
u8 prb_a;
u8 prb_d;
int novly; ///< Number of overlays (1 or more)
int ncfg; ///< Number of configurations (0 or more)
cfw_block *pll;
cfw_image *base; ///< Base sequence
cfw_image *ovly_cfg[CFW_MAX_NOVLY][CFW_MAX_NCFG]; ///< Overlay and cfg
///< patches (if any)
} cfw_pfw;
/**
* Process transition
*
* Sequence for specific state transisitions within the driver
*
*/
typedef struct cfw_transition {
u32 id;
char name[CFW_MAX_ID]; ///< Name of the transition
char desc[CFW_MAX_DESC]; ///< User string
cfw_block *block;
} cfw_transition;
/**
* Device audio mode
*
* Structure linking various operating modes to process flows,
* configurations and sequences
*
*/
typedef struct cfw_mode {
u32 id;
char name[CFW_MAX_ID];
char desc[CFW_MAX_DESC]; ///< User string
u32 flags;
u8 pfw;
u8 ovly;
u8 cfg;
u32 supported_cfgs;
cfw_block *entry;
cfw_block *exit;
} cfw_mode;
/**
* CFW Project
*
* Top level structure describing the CFW project
*/
typedef struct cfw_project {
u32 magic;
u32 bmagic;
u32 size;
u32 cksum;
u32 version;
u32 tstamp;
char name[CFW_MAX_ID]; ///< Project name
char desc[CFW_MAX_DESC]; ///< User string
cfw_dfamily dfamily;
cfw_device device;
u32 flags;
cfw_sclk_source clksrc; ///< Clock source
u32 clkfreq; ///< Clock frequency
cfw_transition *transition[CFW_MAX_TRANSITIONS];
u16 npfw; ///< Number of process flows
u16 nmode; ///< Number of operating modes
cfw_pfw *pfw[CFW_MAX_NPFW]; ///< Indices to PFW locations
cfw_mode *mode[CFW_MAX_MODES];
} cfw_project;
/* @} */
#endif /* CFW_FIRMWARE_H_ */

View File

@@ -1,449 +0,0 @@
#ifndef AIC3XXX_CFW_HOST_BLD
# include <linux/module.h>
# include <linux/delay.h>
# define warn(fmt, ...) printk(fmt "\n", ##__VA_ARGS__)
# define error(fmt, ...) printk(fmt "\n", ##__VA_ARGS__)
#else
# define _GNU_SOURCE
# include <stdlib.h>
# include "utils.h"
# include <string.h>
#endif
#include "aic3xxx_cfw.h"
#include "aic3xxx_cfw_ops.h"
/*
* Firmware version numbers are used to make sure that the
* host and target code stay in sync. It is _not_ recommended
* to provide this number from the outside (E.g., from a makefile)
* Instead, a set of automated tools are relied upon to keep the numbers
* in sync at the time of host testing.
*/
#define CFW_FW_VERSION 0x000100AF
static int aic3xxx_cfw_dlimage(void *pv, cfw_image *pim);
static int aic3xxx_cfw_dlcfg(void *pv, cfw_image *pim);
static void aic3xxx_cfw_dlcmds(void *pv, cfw_block *pb);
cfw_meta_register *aic3xxx_read_meta(cfw_block *pb, int i);
void aic3xxx_wait(void *p, unsigned int reg, u8 mask, u8 data);
static cfw_project *aic3xxx_cfw_unpickle(void *p, int n);
#if defined(AIC3XXX_CFW_HOST_BLD)
// Host test only...
extern const aic3xxx_codec_ops dummy_codec_ops;
extern void *dummy_codec_ops_obj;
void mdelay(int val)
{
int i;
for (i=0; i<val*10; i++);
}
void *aic3xxx_cfw_init(void *pcfw, int n)
{
cfw_state *ps = malloc(sizeof(cfw_state));
ps->ops = &dummy_codec_ops;
ps->ops_obj = dummy_codec_ops_obj;
aic3xxx_cfw_reload(ps, pcfw, n);
return ps;
}
void *aic3xxx_cfw_getpjt(void *ps)
{
return ((cfw_state *)ps)->pjt;
}
// ...till here
#endif
int aic3xxx_cfw_reload(void *pv, void *pcfw, int n)
{
cfw_state *ps = pv;
ps->pjt = aic3xxx_cfw_unpickle(pcfw, n);
ps->cur_mode =
ps->cur_pfw =
ps->cur_ovly =
ps->cur_cfg = -1;
return 0;
}
int aic3xxx_cfw_setmode(void *pv, int mode)
{
cfw_state *ps = pv;
cfw_project *pjt = ps->pjt;
return aic3xxx_cfw_setmode_cfg(pv, mode, pjt->mode[mode]->cfg);
}
int aic3xxx_cfw_setcfg(void *pv, int cfg)
{
cfw_state *ps = pv;
cfw_project *pjt = ps->pjt;
cfw_pfw *pfw;
if (ps->cur_pfw >= pjt->npfw)
return -1; // Non miniDSP
if (!(pjt->mode[ps->cur_mode]->supported_cfgs&(1 << cfg)))
return -1;
if (ps->cur_cfg == cfg)
return 0;
pfw = pjt->pfw[ps->cur_pfw];
ps->cur_cfg = cfg;
return aic3xxx_cfw_dlcfg(pv, pfw->ovly_cfg[ps->cur_ovly][ps->cur_cfg]);
}
int aic3xxx_cfw_setmode_cfg(void *pv, int mode, int cfg)
{
cfw_state *ps = pv;
cfw_project *pjt = ps->pjt;
int which = 0;
cfw_pfw *pfw;
cfw_image *im;
if (mode >= pjt->nmode)
return -1;
if (pjt->mode[mode]->pfw < pjt->npfw) { // New mode uses miniDSP
// FIXME: Add support for entry and exit sequences
pfw = pjt->pfw[pjt->mode[mode]->pfw];
// Make sure cfg is valid and supported in this mode
if (cfg >= pfw->ncfg ||
!(pjt->mode[mode]->supported_cfgs&(1u<<cfg)))
return -1;
/*
* Decisions about which miniDSP to stop/restart are taken
* on the basis of sections present in the _base_ image
* This allows for correct sync mode operation even in cases
* where the base PFW uses both miniDSPs where a particular
* overlay applies only to one
*/
im = pfw->base;
if (im->block[CFW_BLOCK_A_INST])
which |= AIC3XX_COPS_MDSP_A;
if (im->block[CFW_BLOCK_D_INST])
which |= AIC3XX_COPS_MDSP_D;
if (pjt->mode[mode]->pfw != ps->cur_pfw) { // New mode requires different PFW
ps->cur_pfw = pjt->mode[mode]->pfw;
ps->cur_ovly = 0;
ps->cur_cfg = 0;
which = ps->ops->stop(ps->ops_obj, which);
aic3xxx_cfw_dlimage(pv, im);
if (pjt->mode[mode]->ovly && pjt->mode[mode]->ovly < pfw->novly) {
// New mode uses ovly
aic3xxx_cfw_dlimage(pv, pfw->ovly_cfg[pjt->mode[mode]->ovly][cfg]);
} else if (cfg) {
// new mode needs only a cfg change
aic3xxx_cfw_dlimage(pv, pfw->ovly_cfg[0][cfg]);
}
ps->ops->restore(ps->ops_obj, which);
} else if (pjt->mode[mode]->ovly != ps->cur_ovly) {
// New mode requires only an ovly change
which = ps->ops->stop(ps->ops_obj, which);
aic3xxx_cfw_dlimage(pv, pfw->ovly_cfg[pjt->mode[mode]->ovly][cfg]);
ps->ops->restore(ps->ops_obj, which);
} else if (cfg != ps->cur_cfg) { // New mode requires only a cfg change
aic3xxx_cfw_dlcfg(pv, pfw->ovly_cfg[pjt->mode[mode]->ovly][cfg]);
}
ps->cur_ovly = pjt->mode[mode]->ovly;
ps->cur_cfg = cfg;
// FIXME: Update PLL settings if present
// FIXME: This is hack and needs to go one way or another
ps->cur_mode = mode;
aic3xxx_cfw_set_pll(pv, 0);
} else if (pjt->mode[mode]->pfw == 0xFF) { // Bypass mode
// FIXME
} else { // Error
warn("Bad pfw setting detected (%d). Max pfw=%d", pjt->mode[mode]->pfw,
pjt->npfw);
}
ps->cur_mode = mode;
warn("setmode_cfg: DONE (mode=%d pfw=%d ovly=%d cfg=%d)", ps->cur_mode, ps->cur_pfw, ps->cur_ovly, ps->cur_cfg);
return 0;
}
int aic3xxx_cfw_transition(void *pv, char *ttype)
{
cfw_state *ps = pv;
int i;
for (i = 0; i < CFW_TRN_N; ++i) {
if (!strcasecmp(ttype, cfw_transition_id[i])) {
if (ps->pjt->transition[i]) {
DBG("Sending transition %s[%d]", ttype, i);
aic3xxx_cfw_dlcmds(pv, ps->pjt->transition[i]->block);
}
return 0;
}
}
warn("Transition %s not present or invalid", ttype);
return 0;
}
int aic3xxx_cfw_set_pll(void *pv, int asi)
{
// FIXME: no error checks!!
cfw_state *ps = pv;
cfw_project *pjt = ps->pjt;
cfw_pfw *pfw = pjt->pfw[pjt->mode[ps->cur_mode]->pfw];
if (pfw->pll) {
warn("Configuring PLL for ASI%d using PFW%d", asi,
pjt->mode[ps->cur_mode]->pfw);
aic3xxx_cfw_dlcmds(pv, pfw->pll);
}
return 0;
}
static void aic3xxx_cfw_dlcmds(void *pv, cfw_block *pb)
{
cfw_state *ps = pv;
int i = 0, lock = 0;
while (i < pb->ncmds) {
if (CFW_BLOCK_BURSTS(pb->type))
ps->ops->bulk_write(ps->ops_obj, pb->cmd[i].burst->reg.bpod,
pb->cmd[i].burst->length,
pb->cmd[i].burst->data);
else {
cfw_meta_delay d = pb->cmd[i].reg.meta.delay;
cfw_meta_bitop b = pb->cmd[i].reg.meta.bitop;
switch (pb->cmd[i].reg.meta.mcmd) {
case CFW_META_DELAY:
mdelay(d.delay);
break;
case CFW_META_UPDTBITS:
ps->ops->set_bits(ps->ops_obj, pb->cmd[i+1].reg.bpod,
b.mask, pb->cmd[i+1].reg.data);
i++;
break;
case CFW_META_WAITBITS:
aic3xxx_wait(ps, pb->cmd[i+1].reg.bpod,
b.mask, pb->cmd[i+1].reg.data);
i++;
break;
case CFW_META_LOCK:
if (d.delay) {
ps->ops->lock(ps->ops_obj);
lock = 1;
} else {
if (!lock)
error("Attempt to unlock without first locking");
ps->ops->unlock(ps->ops_obj);
lock = 0;
}
break;
default:
ps->ops->reg_write(ps->ops_obj, pb->cmd[i].reg.bpod, pb->cmd[i].reg.data);
}
}
++i;
}
if (lock)
error("exiting blkcmds with lock ON");
}
void aic3xxx_wait(void *p, unsigned int reg, u8 mask, u8 data)
{
cfw_state *ps = p;
while ((ps->ops->reg_read(ps->ops_obj, reg)&mask) != data)
mdelay(2);
}
static int aic3xxx_cfw_dlcfg(void *pv, cfw_image *pim)
{
cfw_state *ps = pv;
int i,run_state,swap;
struct {
u32 mdsp;
int buf_a, buf_b;
u32 swap;
} csecs[] = {
{
.mdsp=AIC3XX_COPS_MDSP_A,
.swap=AIC3XX_ABUF_MDSP_A,
.buf_a=CFW_BLOCK_A_A_COEF,
.buf_b=CFW_BLOCK_A_B_COEF
},
{
.mdsp=AIC3XX_COPS_MDSP_D,
.swap=AIC3XX_ABUF_MDSP_D1,
.buf_a=CFW_BLOCK_D_A1_COEF,
.buf_b=CFW_BLOCK_D_B1_COEF
},
{
.mdsp=AIC3XX_COPS_MDSP_D,
.swap=AIC3XX_ABUF_MDSP_D2,
.buf_a=CFW_BLOCK_D_A2_COEF,
.buf_b=CFW_BLOCK_D_B2_COEF
},
};
DBG("Download CFG %s", pim->name);
run_state = ps->ops->lock(ps->ops_obj);
swap = 0;
for (i = 0; i < sizeof(csecs)/sizeof(csecs[0]); ++i) {
if (pim->block[csecs[i].buf_a]) {
if (run_state & csecs[i].mdsp) {
aic3xxx_cfw_dlcmds(pv, pim->block[csecs[i].buf_a]);
swap |= csecs[i].swap;
aic3xxx_cfw_dlcmds(pv, pim->block[csecs[i].buf_b]);
} else {
aic3xxx_cfw_dlcmds(pv, pim->block[csecs[i].buf_a]);
aic3xxx_cfw_dlcmds(pv, pim->block[csecs[i].buf_b]);
}
}
}
if (swap) // Check needed? FIXME
ps->ops->bswap(ps->ops_obj, swap);
ps->ops->unlock(ps->ops_obj);
return 0;
}
static int aic3xxx_cfw_dlimage(void *pv, cfw_image *pim)
{
//cfw_state *ps = pv;
int i;
DBG("Download IMAGE %s", pim->name);
for (i = 0; i < CFW_BLOCK_N; ++i)
if (pim->block[i])
aic3xxx_cfw_dlcmds(pv, pim->block[i]);
return 0;
}
# define FW_NDX2PTR(x, b) do { \
x = (void *)((u8 *)(b) + ((int)(x))); \
} while (0)
static void aic3xxx_cfw_unpickle_block(cfw_block *pb, void *p)
{
int i;
if (CFW_BLOCK_BURSTS(pb->type)) {
for (i = 0; i < pb->ncmds; ++i) {
FW_NDX2PTR(pb->cmd[i].burst, p);
}
}
}
static void aic3xxx_cfw_unpickle_image(cfw_image *im, void *p)
{
int i;
for (i = 0; i < CFW_BLOCK_N; ++i)
if (im->block[i]) {
FW_NDX2PTR(im->block[i], p);
aic3xxx_cfw_unpickle_block(im->block[i], p);
}
}
#ifndef AIC3XXX_CFW_HOST_BLD
static
#endif
unsigned int crc32(unsigned int *pdata, int n)
{
u32 crc = 0, i, crc_poly = 0x04C11DB7; /* CRC - 32 */
u32 msb;
u32 residue_value;
int bits;
for (i = 0; i < (n >> 2); i++) {
bits = 32;
while (--bits >= 0) {
msb = crc & 0x80000000;
crc = (crc << 1) ^ ((*pdata >> bits) & 1);
if (msb)
crc = crc ^ crc_poly;
}
pdata++;
}
switch (n & 3) {
case 0:
break;
case 1:
residue_value = (*pdata & 0xFF);
bits = 8;
break;
case 2:
residue_value = (*pdata & 0xFFFF);
bits = 16;
break;
case 3:
residue_value = (*pdata & 0xFFFFFF);
bits = 24;
break;
}
if (n & 3) {
while (--bits >= 0) {
msb = crc & 0x80000000;
crc = (crc << 1) ^ ((residue_value >> bits) & 1);
if (msb)
crc = crc ^ crc_poly;
}
}
return (crc);
}
static int crc_chk(void *p, int n)
{
cfw_project *pjt = (void *)p;
u32 crc = pjt->cksum, crc_comp;
pjt->cksum = 0;
DBG("Entering crc %d",n);
crc_comp = crc32(p, n);
if (crc_comp != crc) {
DBG("CRC mismatch 0x%08X != 0x%08X", crc, crc_comp);
return 0; // Dead code
}
DBG("CRC pass");
pjt->cksum = crc;
return 1;
}
#ifndef AIC3XXX_CFW_HOST_BLD
static
#endif
cfw_project *aic3xxx_cfw_unpickle(void *p, int n)
{
cfw_project *pjt = p;
int i, j, k;
if (pjt->magic != CFW_FW_MAGIC ||
pjt->size != n ||
pjt->bmagic != CFW_FW_VERSION ||
!crc_chk(p, n)) {
error("magic:0x%08X!=0x%08X || size:%d!=%d || version:0x%08X!=0x%08X",
pjt->magic, CFW_FW_MAGIC, pjt->size, n, pjt->cksum,
CFW_FW_VERSION);
return NULL;
}
DBG("Loaded firmware inside unpickle\n");
for (i = 0; i < CFW_MAX_TRANSITIONS; i++) {
if (pjt->transition[i]) {
FW_NDX2PTR(pjt->transition[i], p);
FW_NDX2PTR(pjt->transition[i]->block, p);
aic3xxx_cfw_unpickle_block(pjt->transition[i]->block, p);
}
}
for (i = 0; i < pjt->npfw; i++) {
DBG("loading pfw %d\n",i);
FW_NDX2PTR(pjt->pfw[i], p);
if (pjt->pfw[i]->base) {
FW_NDX2PTR(pjt->pfw[i]->base, p);
aic3xxx_cfw_unpickle_image(pjt->pfw[i]->base, p);
}
if (pjt->pfw[i]->pll) {
FW_NDX2PTR(pjt->pfw[i]->pll, p);
aic3xxx_cfw_unpickle_block(pjt->pfw[i]->pll, p);
}
for (j =0; j < pjt->pfw[i]->novly; ++j)
for (k =0; k < pjt->pfw[i]->ncfg; ++k) {
FW_NDX2PTR(pjt->pfw[i]->ovly_cfg[j][k], p);
aic3xxx_cfw_unpickle_image(pjt->pfw[i]->ovly_cfg[j][k], p);
}
}
DBG("loaded pfw's\n");
for (i = 0; i < pjt->nmode; i++) {
FW_NDX2PTR(pjt->mode[i], p);
if (pjt->mode[i]->entry) {
FW_NDX2PTR(pjt->mode[i]->entry, p);
aic3xxx_cfw_unpickle_block(pjt->mode[i]->entry, p);
}
if (pjt->mode[i]->exit) {
FW_NDX2PTR(pjt->mode[i]->exit, p);
aic3xxx_cfw_unpickle_block(pjt->mode[i]->exit, p);
}
}
DBG("loaded modes\n");
return pjt;
}

View File

@@ -1,70 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef AIC3XXX_CFW_OPS_H_
#define AIC3XXX_CFW_OPS_H_
#ifdef AIC3XXX_CFW_HOST_BLD
void *aic3xxx_cfw_init(void *pcfw, int n);
void *aic3xxx_cfw_getpjt(void *ps);
cfw_project *aic3xxx_cfw_unpickle(void *,int);
unsigned int crc32(unsigned int *pdata, int n);
#endif
int aic3xxx_cfw_reload(void *pv, void *pcfw, int n);
int aic3xxx_cfw_setmode(void *pv, int mode);
int aic3xxx_cfw_setmode_cfg(void *pv, int mode, int cfg);
int aic3xxx_cfw_setcfg(void *pv, int cfg);
int aic3xxx_cfw_transition(void *pv, char *ttype);
int aic3xxx_cfw_set_pll(void *pv, int asi);
#define AIC3XX_COPS_MDSP_D (0x00000003u)
#define AIC3XX_COPS_MDSP_A (0x00000030u)
#define AIC3XX_COPS_MDSP_ALL (AIC3XX_COPS_MDSP_D|AIC3XX_COPS_MDSP_A)
#define AIC3XX_ABUF_MDSP_D1 (0x00000001u)
#define AIC3XX_ABUF_MDSP_D2 (0x00000002u)
#define AIC3XX_ABUF_MDSP_A (0x00000010u)
#define AIC3XX_ABUF_MDSP_ALL \
(AIC3XX_ABUF_MDSP_D1| AIC3XX_ABUF_MDSP_D2| AIC3XX_ABUF_MDSP_A)
typedef struct aic3xxx_codec_ops {
int (*reg_read)(void *p, unsigned int reg);
int (*reg_write)(void *p, unsigned int reg,
unsigned char val);
int (*set_bits)(void *p, unsigned int reg,
unsigned char mask, unsigned char val);
int (*bulk_read)(void *p, unsigned int reg,
int count, u8 *buf);
int (*bulk_write)(void *p, unsigned int reg,
int count, const u8 *buf);
int (*lock)(void *p);
int (*unlock)(void *p);
int (*stop)(void *p, int mask);
int (*restore)(void *p, int runstate);
int (*bswap)(void *p,int mask);
} aic3xxx_codec_ops;
typedef struct cfw_state {
cfw_project *pjt;
const aic3xxx_codec_ops *ops;
void *ops_obj;
int cur_mode;
int cur_pfw;
int cur_ovly;
int cur_cfg;
} cfw_state;
#ifndef AIC3XXX_CFW_HOST_BLD
#ifdef DEBUG
# define DBG(fmt,...) printk("CFW[%s:%d]: " fmt "\n", \
__FILE__, __LINE__, ##__VA_ARGS__)
#else
# define DBG(fmt,...)
#endif
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,621 +0,0 @@
/*
* linux/sound/soc/codecs/tlv320aic3111.h
*
* Copyright (C) 2010 Texas Instruments, Inc.
*
* This package 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.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* History:
*
* Rev 0.1 ASoC driver support Mistral 14-04-2010
*
* Rev 0.2 Updated based Review Comments Mistral 29-06-2010
*
* Rev 0.3 Updated for Codec Family Compatibility 12-07-2010
*/
#ifndef _TLV320AIC3111_H
#define _TLV320AIC3111_H
/* #define AUDIO_NAME "aic3111"
#define AIC3111_VERSION "0.1"
*/
/*
******************AIC31xx CODEC SUPPORT *****************
* THE CURRENT CODE-BASE SUPPORTS BUILDING of the CODEC
* DRIVER FOR AIC3111, AIC3110, AIC3100 and AIC3120.
* PLEASE NOTE THAT FOR EACH OF THE ABOVE CODECS, the
* Linux Developer needs to enable a particular flag in
* this header file before performing a build of the
* Audio Codec Driver.
*********************************************************
*/
//#define AIC3111_CODEC_SUPPORT
#define AIC3110_CODEC_SUPPORT
//#define AIC3100_CODEC_SUPPORT
//#define AIC3120_CODEC_SUPPORT
/* NOTE THAT AIC3110 and AIC3100 do not support miniDSP */
#ifdef AIC3110_CODEC_SUPPORT
#undef CONFIG_MINI_DSP
#define AUDIO_NAME "aic3110"
#define AIC3111_VERSION "0.1"
#endif
#ifdef AIC3100_CODEC_SUPPORT
#undef CONFIG_MINI_DSP
#define AUDIO_NAME "aic3100"
#define AIC3111_VERSION "0.1"
#endif
#ifdef AIC3120_CODEC_SUPPORT
#undef CONFIG_MINI_DSP
#define AUDIO_NAME "aic3120"
#define AIC3111_VERSION "0.1"
#endif
/* The user has a choice to enable or disable miniDSP code
* when building for AIC3111 Codec.
*/
#ifdef AIC3111_CODEC_SUPPORT
/* Macro enables or disables support for miniDSP in the driver */
//#define CONFIG_MINI_DSP
#undef CONFIG_MINI_DSP
#define AUDIO_NAME "aic3111"
#define AIC3111_VERSION "0.1"
#endif
/* Enable slave / master mode for codec */
//#define AIC3111_MCBSP_SLAVE
#undef AIC3111_MCBSP_SLAVE
/* Enable register caching on write */
#define EN_REG_CACHE
/* Enable headset detection */
#define HEADSET_DETECTION
/* AIC3111 supported sample rate are 8k to 192k */
#define AIC3111_RATES SNDRV_PCM_RATE_8000_192000
/* AIC3111 supports the word formats 16bits, 20bits, 24bits and 32 bits */
#define AIC3111_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
| SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
#define AIC3111_FREQ_12000000 12000000
#define AIC3111_FREQ_24000000 24000000
#define AIC3111_FREQ_11289600 11289600
/* AIC3111 register space */
#define AIC31xx_CACHEREGNUM 384
/* Audio data word length = 16-bits (default setting) */
#define AIC3111_WORD_LEN_16BITS 0x00
#define AIC3111_WORD_LEN_20BITS 0x01
#define AIC3111_WORD_LEN_24BITS 0x02
#define AIC3111_WORD_LEN_32BITS 0x03
#define DATA_LEN_SHIFT 4
/* sink: name of target widget */
#define AIC3111_WIDGET_NAME 0
/* control: mixer control name */
#define AIC3111_CONTROL_NAME 1
/* source: name of source name */
#define AIC3111_SOURCE_NAME 2
/* D15..D8 aic3111 register offset */
#define AIC3111_REG_OFFSET_INDEX 0
/* D7...D0 register data */
#define AIC3111_REG_DATA_INDEX 1
/* Serial data bus uses I2S mode (Default mode) */
#define AIC3111_I2S_MODE 0x00
#define AIC3111_DSP_MODE 0x01
#define AIC3111_RIGHT_JUSTIFIED_MODE 0x02
#define AIC3111_LEFT_JUSTIFIED_MODE 0x03
#define AUDIO_MODE_SHIFT 6
/* number of codec specific register for configuration */
#define NO_FEATURE_REGS 2
/* 8 bit mask value */
#define AIC3111_8BITS_MASK 0xFF
#ifndef AIC3120_CODEC_SUPPORT /* for AIC3111, AIC3110 and AIC3100 */
/* ****************** Page 0 Registers **************************************/
#define PAGE_SELECT 0
#define RESET 1
#define CLK_REG_1 4
#define CLK_REG_2 5
#define CLK_REG_3 6
#define CLK_REG_4 7
#define CLK_REG_5 8
#define NDAC_CLK_REG 11
#define MDAC_CLK_REG 12
#define DAC_OSR_MSB 13
#define DAC_OSR_LSB 14
#define NADC_CLK_REG 18
#define MADC_CLK_REG 19
#define ADC_OSR_REG 20
#define CLK_MUX_REG 25
#define CLK_MVAL_REG 26
#define INTERFACE_SET_REG_1 27
#define DATA_SLOT_OFFSET 28
#define INTERFACE_SET_REG_2 29
#define BCLK_N_VAL 30
#define INTERFACE_SET_REG_3 31
#define INTERFACE_SET_REG_4 32
#define INTERFACE_SET_REG_5 33
#define I2C_BUS_COND 34
#define INTL_CRTL_REG_1 48
#define INTL_CRTL_REG_2 49
#define GPIO_CRTL_REG_1 51
#define DAC_PRB_SEL_REG 60
#define ADC_PRB_SEL_REG 61
#define DAC_CHN_REG 63
#define DAC_MUTE_CTRL_REG 64
#define LDAC_VOL 65
#define RDAC_VOL 66
#define HEADSET_DETECT 67
#define DRC_CTL_REG_1 68
#define DRC_CTL_REG_2 69
#define DRC_CTL_REG_3 70
#define LEFT_BEEP_GEN 71
#define RIGHT_BEEP_GEN 72
#define BEEP_LENGTH_MSB 73
#define BEEP_LENGTH_MID 74
#define BEEP_LENGTH_LSB 75
#define BEEP_SINX_MSB 76
#define BEEP_SINX_LSB 77
#define BEEP_COSX_MSB 78
#define BEEP_COSX_LSB 79
#define ADC_DIG_MIC 81
#define ADC_FGA 82
#define ADC_CGA 83
#define AGC_CTRL_1 86
#define AGC_CTRL_2 87
#define AGC_CTRL_3 88
#define AGC_CTRL_4 89
#define AGC_CTRL_5 90
#define AGC_CTRL_6 91
#define AGC_CTRL_7 92
#define AGC_CTRL_8 93
#define ADC_DC_1 102
#define ADC_DC_2 103
#define PIN_VOL_CTRL 116
#define PIN_VOL_GAIN 117
/******************** Page 1 Registers **************************************/
#define PAGE_1 128
#define HEADPHONE_DRIVER (PAGE_1 + 31)
#define CLASSD_SPEAKER_AMP (PAGE_1 + 32)
#define HP_POP_CTRL (PAGE_1 + 33)
#define PGA_RAMP_CTRL (PAGE_1 + 34)
#define DAC_MIX_CTRL (PAGE_1 + 35)
#define L_ANLOG_VOL_2_HPL (PAGE_1 + 36)
#define R_ANLOG_VOL_2_HPR (PAGE_1 + 37)
#define L_ANLOG_VOL_2_SPL (PAGE_1 + 38)
#define R_ANLOG_VOL_2_SPR (PAGE_1 + 39)
#define HPL_DRIVER (PAGE_1 + 40)
#define HPR_DRIVER (PAGE_1 + 41)
#define SPL_DRIVER (PAGE_1 + 42)
#define SPR_DRIVER (PAGE_1 + 43)
#define HP_DRIVER_CTRL (PAGE_1 + 44)
#define MICBIAS_CTRL (PAGE_1 + 46)
#define MIC_PGA (PAGE_1 + 47)
#define MIC_GAIN (PAGE_1 + 48)
#define ADC_IP_SEL (PAGE_1 + 49)
#define CM_SET (PAGE_1 + 50)
#define L_MICPGA_P (PAGE_1 + 52)
#define L_MICPGA_N (PAGE_1 + 54)
#define R_MICPGA_P (PAGE_1 + 55)
#define R_MICPGA_N (PAGE_1 + 57)
/****************************************************************************/
/****************************************************************************/
#define BIT7 (1 << 7)
#define BIT6 (1 << 6)
#define BIT5 (1 << 5)
#define BIT4 (1 << 4)
#define BIT3 (1 << 3)
#define BIT2 (1 << 2)
#define BIT1 (1 << 1)
#define BIT0 (1 << 0)
#define HP_UNMUTE BIT2
#define HPL_UNMUTE BIT3
#define ENABLE_DAC_CHN (BIT6 | BIT7)
#define ENABLE_ADC_CHN (BIT6 | BIT7)
#define BCLK_DIR_CTRL (BIT2 | BIT3)
#define CODEC_CLKIN_MASK 0x03
#define MCLK_2_CODEC_CLKIN 0x00
#define CODEC_MUX_VALUE 0X03
/*Bclk_in selection*/
#define BDIV_CLKIN_MASK 0x03
#define DAC_MOD_CLK_2_BDIV_CLKIN BIT0
#define SOFT_RESET 0x01
#define PAGE0 0x00
#define PAGE1 0x01
#define BIT_CLK_MASTER BIT3
#define WORD_CLK_MASTER BIT2
#define HIGH_PLL BIT6
#define ENABLE_PLL BIT7
#define ENABLE_NDAC BIT7
#define ENABLE_MDAC BIT7
#define ENABLE_NADC BIT7
#define ENABLE_MADC BIT7
#define ENABLE_BCLK BIT7
#define LDAC_2_LCHN BIT4
#define RDAC_2_RCHN BIT2
#define RDAC_2_RAMP BIT2
#define LDAC_2_LAMP BIT6
#define LDAC_CHNL_2_HPL BIT3
#define RDAC_CHNL_2_HPR BIT3
#define SOFT_STEP_2WCLK BIT0
#define MUTE_ON 0x00
#define DEFAULT_VOL 0x0
//#define DEFAULT_VOL 0xAf
#define DISABLE_ANALOG BIT3
#define LDAC_2_HPL_ROUTEON BIT3
#define RDAC_2_HPR_ROUTEON BIT3
#define LINEIN_L_2_LMICPGA_10K BIT6
#define LINEIN_L_2_LMICPGA_20K BIT7
#define LINEIN_L_2_LMICPGA_40K (0x3 << 6)
#define LINEIN_R_2_RMICPGA_10K BIT6
#define LINEIN_R_2_RMICPGA_20K BIT7
#define LINEIN_R_2_RMICPGA_40K (0x3 << 6)
/****************************************************************************
* DAPM widget related #defines
***************************************************************************
*/
#define LMUTE_ENUM 0
#define RMUTE_ENUM 1
#define DACEXTRA_ENUM 2
#define DACCONTROL_ENUM 3
#define SOFTSTEP_ENUM 4
#define BEEP_ENUM 5
#define MICBIAS_ENUM 6
#define DACLEFTIP_ENUM 7
#define DACRIGHTIP_ENUM 8
#define VOLTAGE_ENUM 9
#define HSET_ENUM 10
#define DRC_ENUM 11
#define MIC1LP_ENUM 12
#define MIC1RP_ENUM 13
#define MIC1LM_ENUM 14
#define MIC_ENUM 15
#define CM_ENUM 16
#define MIC1LMM_ENUM 17
#define MIC1_ENUM 18
#define MIC2_ENUM 19
#define MIC3_ENUM 20
#define ADCMUTE_ENUM 21
#endif
#ifdef AIC3120_CODEC_SUPPORT /*for AIC3120 */
/* ****************** Page 0 Registers **************************************/
#define PAGE_SELECT 0
#define RESET 1
#define CLK_REG_1 4
#define CLK_REG_2 5
#define CLK_REG_3 6
#define CLK_REG_4 7
#define CLK_REG_5 8
#define NDAC_CLK_REG 11
#define MDAC_CLK_REG 12
#define DAC_OSR_MSB 13
#define DAC_OSR_LSB 14
#define NADC_CLK_REG 18
#define MADC_CLK_REG 19
#define ADC_OSR_REG 20
#define CLK_MUX_REG 25
#define CLK_MVAL_REG 26
#define INTERFACE_SET_REG_1 27
#define DATA_SLOT_OFFSET 28
#define INTERFACE_SET_REG_2 29
#define BCLK_N_VAL 30
#define INTERFACE_SET_REG_3 31
#define INTERFACE_SET_REG_4 32
#define INTERFACE_SET_REG_5 33
#define I2C_BUS_COND 34
#define INTL_CRTL_REG_1 48
#define INTL_CRTL_REG_2 49
#define GPIO_CRTL_REG_1 51
#define DAC_PRB_SEL_REG 60
#define ADC_PRB_SEL_REG 61
#define DAC_CHN_REG 63
#define DAC_MUTE_CTRL_REG 64
#define LDAC_VOL 65 /*Mistral: AIC3120 has mono dac...renamed from LDAC_VOL to DAC_VOL.*/
#define DAC_VOL 65 /*Mistral:..DUAL definition for compatibility*/
/*Mistral: 3120 is mono..RDAC_VOL is reserved..register removed*/
#define HEADSET_DETECT 67
#define DRC_CTL_REG_1 68
#define DRC_CTL_REG_2 69
#define DRC_CTL_REG_3 70
/* 3120 does not have beep generation circuits...So removed beep related registers*/
#define ADC_DIG_MIC 81
#define ADC_FGA 82
#define ADC_CGA 83
#define AGC_CTRL_1 86
#define AGC_CTRL_2 87
#define AGC_CTRL_3 88
#define AGC_CTRL_4 89
#define AGC_CTRL_5 90
#define AGC_CTRL_6 91
#define AGC_CTRL_7 92
#define AGC_CTRL_8 93
#define ADC_DC_1 102
#define ADC_DC_2 103
#define PIN_VOL_CTRL 116
#define PIN_VOL_GAIN 117
/******************** Page 1 Registers **************************************/
#define PAGE_1 128
#define HEADPHONE_DRIVER (PAGE_1 + 31)
#define CLASSD_SPEAKER_AMP (PAGE_1 + 32)
#define HP_POP_CTRL (PAGE_1 + 33)
#define PGA_RAMP_CTRL (PAGE_1 + 34)
#define DAC_MIX_CTRL (PAGE_1 + 35)
#define L_ANLOG_VOL_2_HPL (PAGE_1 + 36)
#define ANALOG_HPOUT_VOL (PAGE_1 + 36)
/*Mistral: 3120 DAC is mono.. R_ANALOG_VOL_2_HPR register is removed*/
#define L_ANLOG_VOL_2_SPL (PAGE_1 + 38)
#define ANALOG_CDOUT_VOL (PAGE_1 + 38) /*Mistral: Dual definition for compatibility*/
/*Mistral: 3120 DAC is mono.. R_ANALOG_VOL_2_SPR register is removed*/
#define HPL_DRIVER (PAGE_1 + 40) /*Mistral: kept for compatibility*/
#define HP_DRIVER (PAGE_1 + 40) /*Mistral: Dual definition for compatibility*/
#define HPOUT_DRIVER (PAGE_1 + 40) /*Mistral: Triple definition for compatibility*/
/*Mistral: 3120 DAC is mono.. HPR_DRIVER register is removed*/
#define SPL_DRIVER (PAGE_1 + 42) /*Mistral: kept for compatibility*/
#define SP_DRIVER (PAGE_1 + 42) /*Mistral: Dual Definition for compatibility*/
#define CD_OUT_DRIVER (PAGE_1 + 42) /*Mistral: Triple definition for compatibility*/
/*Mistral: 3120 DAC is mono.. HPR_DRIVER register is removed*/
#define HP_DRIVER_CTRL (PAGE_1 + 44)
#define MICBIAS_CTRL (PAGE_1 + 46)
#define MIC_PGA (PAGE_1 + 47)
#define MIC_GAIN (PAGE_1 + 48)
#define ADC_IP_SEL (PAGE_1 + 49)
#define CM_SET (PAGE_1 + 50)
#define L_MICPGA_P (PAGE_1 + 52)
#define L_MICPGA_N (PAGE_1 + 54)
#define R_MICPGA_P (PAGE_1 + 55)
#define R_MICPGA_N (PAGE_1 + 57)
/****************************************************************************/
/****************************************************************************/
#define BIT7 (1 << 7)
#define BIT6 (1 << 6)
#define BIT5 (1 << 5)
#define BIT4 (1 << 4)
#define BIT3 (1 << 3)
#define BIT2 (1 << 2)
#define BIT1 (1 << 1)
#define BIT0 (1 << 0)
#define HP_UNMUTE BIT2 /*Mistral: Kept for compatibility*/
#define HPL_UNMUTE BIT3
#define ENABLE_DAC_CHN BIT7 /*Mistral reg [0][63] only right DAC is present*/
#define ENABLE_ADC_CHN (BIT6 | BIT7)
#define BCLK_DIR_CTRL (BIT2 | BIT3)
#define CODEC_CLKIN_MASK 0x03
#define MCLK_2_CODEC_CLKIN 0x00
#define CODEC_MUX_VALUE 0X03
/*Bclk_in selection*/
#define BDIV_CLKIN_MASK 0x03
#define DAC_MOD_CLK_2_BDIV_CLKIN BIT0
#define SOFT_RESET 0x01
#define PAGE0 0x00
#define PAGE1 0x01
#define BIT_CLK_MASTER BIT3
#define WORD_CLK_MASTER BIT2
#define HIGH_PLL BIT6
#define ENABLE_PLL BIT7
#define ENABLE_NDAC BIT7
#define ENABLE_MDAC BIT7
#define ENABLE_NADC BIT7
#define ENABLE_MADC BIT7
#define ENABLE_BCLK BIT7
#define LDAC_2_LCHN BIT4
/*Mistral: RDAC_2_LCHN...Removed as its reserved*/
#define RDAC_2_RAMP BIT2 /*Mistral: kept for compatibility*/
#define LDAC_2_LAMP BIT6
#define LDAC_CHNL_2_HPL BIT3
#define SOFT_STEP_2WCLK BIT0
#define MUTE_ON 0x00
#define DEFAULT_VOL 0x0
#define DISABLE_ANALOG BIT3
#define LDAC_2_HPL_ROUTEON BIT3
/*#define RDAC_2_HPR_ROUTEON BIT3*/ /*Mistral: NOT present in AIC3120*/
#define LINEIN_L_2_LMICPGA_10K BIT6
#define LINEIN_L_2_LMICPGA_20K BIT7
#define LINEIN_L_2_LMICPGA_40K (0x3 << 6)
#define LINEIN_R_2_RMICPGA_10K BIT6
#define LINEIN_R_2_RMICPGA_20K BIT7
#define LINEIN_R_2_RMICPGA_40K (0x3 << 6)
/****************************************************************************
* DAPM widget related #defines
***************************************************************************
*/
#define LMUTE_ENUM 0
/*#define RMUTE_ENUM 1*/ /*Mistral: NOT Present in AIC3120*/
#define DACEXTRA_ENUM 2
#define DACCONTROL_ENUM 3
#define SOFTSTEP_ENUM 4
/*#define BEEP_ENUM 5*/ /*Mistral: not present in AIC3120*/
#define MICBIAS_ENUM 6
#define DACLEFTIP_ENUM 7
#define DACRIGHTIP_ENUM 8
#define VOLTAGE_ENUM 9
#define HSET_ENUM 10
#define DRC_ENUM 11
#define MIC1LP_ENUM 12
#define MIC1RP_ENUM 13
#define MIC1LM_ENUM 14
#define MIC_ENUM 15
#define CM_ENUM 16
#define MIC1LMM_ENUM 17
#define MIC1_ENUM 18
#define MIC2_ENUM 19
#define MIC3_ENUM 20
#define ADCMUTE_ENUM 21
#endif
/*****************************************************************************
* Structures Definitions
*****************************************************************************
*/
/*
*----------------------------------------------------------------------------
* @struct aic3111_setup_data |
* i2c specific data setup for AIC3111.
* @field unsigned short |i2c_address |
* Unsigned short for i2c address.
*----------------------------------------------------------------------------
*/
struct aic3111_setup_data
{
unsigned short i2c_address;
};
/*
*----------------------------------------------------------------------------
* @struct aic3111_priv |
* AIC3111 priviate data structure to set the system clock, mode and
* page number.
* @field u32 | sysclk |
* system clock
* @field s32 | master |
* master/slave mode setting for AIC3111
* @field u8 | page_no |
* page number. Here, page 0 and page 1 are used.
*----------------------------------------------------------------------------
*/
struct aic3111_priv
{
u32 sysclk;
s32 master;
u8 page_no;
};
/*
*----------------------------------------------------------------------------
* @struct aic3111_configs |
* AIC3111 initialization data which has register offset and register
* value.
* @field u16 | reg_offset |
* AIC3111 Register offsets required for initialization..
* @field u8 | reg_val |
* value to set the AIC3111 register to initialize the AIC3111.
*----------------------------------------------------------------------------
*/
struct aic3111_configs
{
u16 reg_offset;
u8 reg_val;
};
/*
*----------------------------------------------------------------------------
* @struct aic3111_rate_divs |
* Setting up the values to get different freqencies
*
* @field u32 | mclk |
* Master clock
* @field u32 | rate |
* sample rate
* @field u8 | p_val |
* value of p in PLL
* @field u32 | pll_j |
* value for pll_j
* @field u32 | pll_d |
* value for pll_d
* @field u32 | dosr |
* value to store dosr
* @field u32 | ndac |
* value for ndac
* @field u32 | mdac |
* value for mdac
* @field u32 | aosr |
* value for aosr
* @field u32 | nadc |
* value for nadc
* @field u32 | madc |
* value for madc
* @field u32 | blck_N |
* value for block N
* @field u32 | aic3111_configs |
* configurations for aic3111 register value
*----------------------------------------------------------------------------
*/
struct aic3111_rate_divs
{
u32 mclk;
u32 rate;
u8 p_val;
u8 pll_j;
u16 pll_d;
u16 dosr;
u8 ndac;
u8 mdac;
u8 aosr;
u8 nadc;
u8 madc;
u8 blck_N;
struct aic3111_configs codec_specific_regs[NO_FEATURE_REGS];
};
/*
*----------------------------------------------------------------------------
* @struct snd_soc_codec_dai |
* It is SoC Codec DAI structure which has DAI capabilities viz.,
* playback and capture, DAI runtime information viz. state of DAI
* and pop wait state, and DAI private data.
*----------------------------------------------------------------------------
*/
extern struct snd_soc_dai tlv320aic3111_dai;
#endif /* _TLV320AIC3111_H */

View File

@@ -1,321 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
unsigned char default_firmware[] = {
237,241,209,192,175, 0, 1, 0,219, 19, 0, 0, 28, 84, 36, 37,
0, 0, 0, 0,161, 85,149, 79, 70,105,114,109,119, 97,114,101,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 2, 13, 0, 0, 8, 2, 0, 0,
0, 0, 0, 0, 0,240, 73, 2,172, 3, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 32, 6, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,131, 17, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105,110,105,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73,110,105,116,105, 97,108,105,122, 97,116,105,111,110, 32,115,
101,113,117,101,110, 99,101, 32, 40, 97,112,112,108,105,101,100,
32,111,110,108,121, 32,111,110, 32,115,121,115,116,101,109, 32,
98,111,111,116, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
244, 5, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0,100, 0,128, 0,
0, 1, 1, 0, 0, 1,122, 1, 0, 0, 4, 51, 0, 0, 82, 0,
0, 0, 67,151, 0, 1,119,127, 0, 0,129, 1, 0, 4, 11, 1,
100,101,102, 97,117,108,116, 0, 98, 97,115,101, 95,109, 97,105,
110, 95, 82, 97,116,101, 52, 56, 46, 99,102,103, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0,
253, 11, 0, 0,120, 9, 0, 0,121, 12, 0, 0,254, 14, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,100,101,102, 97,117,108,116, 47,
98, 97,115,101, 95,109, 97,105,110, 95, 82, 97,116,101, 52, 56,
46, 99,102,103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 8,115,247,
0, 0, 0, 0,137, 55, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,232, 11, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 1, 0, 0, 0,
244, 11, 0, 0, 2, 0, 0, 0, 0, 0, 60, 1, 1, 0, 0, 0,
0, 29, 0, 0, 0, 0, 0,129,127, 0, 0, 6, 33, 0, 0,129,
63, 0, 0, 7, 5, 0, 0, 8, 4, 0, 0, 9,176, 0, 0,129,
127, 0, 0, 10, 1, 0, 0,129,127, 0, 0, 11, 2, 0, 0,129,
127, 0, 0, 12, 8, 0, 0, 13, 0, 0, 0, 14,128, 0, 0, 18,
130, 0, 0, 19,136, 0, 0, 20,128, 0, 0,129, 3, 0, 4, 11,
0, 0, 0,129,127, 0, 4, 12, 4, 0, 0,129,127, 0, 4, 13,
32, 0, 0,129,119, 0, 4, 14, 0, 0, 4,119,240, 0, 4,120,
0,100, 0, 20,128,120, 0, 20, 0,100,101,102, 97,117,108,116,
47, 80, 97,116, 99,104, 95, 98, 97,115,101, 95,109, 97,105,110,
95, 82, 97,116,101, 52, 56, 46, 99,102,103, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,233, 14, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0, 0, 1, 0, 0,
0,245, 14, 0, 0, 2, 0, 0, 0, 0, 0, 60, 1, 1,100,101,
102, 97,117,108,116, 47, 80, 97,116, 99,104, 95, 98, 97,115,101,
95,115,112,107, 95, 82, 97,116,101, 52, 56, 46, 99,102,103, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 96, 8,115,247, 0, 0, 0, 0,233, 58, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 17,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 36,
115,247, 1, 0, 0, 0,122, 17, 0, 0, 2, 0, 0, 0, 0, 0,
60, 1, 1, 0, 0, 0, 0,100,101,102, 97,117,108,116, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,261 +0,0 @@
/*
* linux/sound/soc/codecs/tlv320aic326x.h
*
* Copyright (C) 2011 TI Solutions Pvt Ltd.
*
* Based on sound/soc/codecs/tlv320aic3262.c
*
* This package 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.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* The TLV320AIC3262 is a flexible, low-power, low-voltage stereo audio
* codec with digital microphone inputs and programmable outputs.
*
* History:
*
* Rev 0.1 ASoC driver support TI 20-01-2011
*
* The AIC325x ASoC driver is ported for the codec AIC3262.
* Rev 0.2 ASoC driver support TI 21-03-2011
* The AIC326x ASoC driver is updated for linux 2.6.32 Kernel.
* Rev 0.3 ASoC driver support TI 20-04-2011
* The AIC326x ASoC driver is ported to 2.6.35 omap4 kernel
*/
#ifndef _TLV320AIC3262_H
#define _TLV320AIC3262_H
#include "aic3xxx_cfw.h"
#include "aic3xxx_cfw_ops.h"
#include <linux/switch.h>
/*#ifdef DEBUG
#define dprintk(x...) printk(x)
#define DBG(x...) printk(x)
#else
#define dprintk(x...)
#define DBG(x...)
#endif
*/
#define AUDIO_NAME "aic3262"
#define AIC3262_VERSION "1.1"
/* Macro to enable the inclusion of tiload kernel driver */
#define AIC3262_TiLoad
//#define AIC3262_SYNC_MODE
#undef AIC3262_SYNC_MODE
#define AIC3262_ASI1_MASTER
//#undef AIC3262_ASI1_MASTER
//#define AIC3262_ASI2_MASTER
#undef AIC3262_ASI2_MASTER
//#define AIC3262_ASI3_MASTER
#undef AIC3262_ASI3_MASTER
/* Macro for McBsp master / slave configuration */
#define AIC3262_MCBSP_SLAVE /*3262 master*/
//#undef AIC3262_MCBSP_SLAVE
/* Enable this macro allow for different ASI formats */
//#define ASI_MULTI_FMT
#undef ASI_MULTI_FMT
/* Enable register caching on write */
//#define EN_REG_CACHE
/* Enable or disable controls to have Input routing*/
//#define FULL_IN_CNTL
#undef FULL_IN_CNTL
/* AIC3262 supported sample rate are 8k to 192k */
#define AIC3262_RATES SNDRV_PCM_RATE_8000_192000
/* AIC3262 supports the word formats 16bits, 20bits, 24bits and 32 bits */
#define AIC3262_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
| SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
#define AIC3262_FREQ_11289600 11289600
#define AIC3262_FREQ_12000000 12000000
#define AIC3262_FREQ_19200000 19200000
#define AIC3262_FREQ_24000000 24000000
#define AIC3262_FREQ_38400000 38400000
/* Audio data word length = 16-bits (default setting) */
#define AIC3262_WORD_LEN_16BITS 0x00
#define AIC3262_WORD_LEN_20BITS 0x01
#define AIC3262_WORD_LEN_24BITS 0x02
#define AIC3262_WORD_LEN_32BITS 0x03
/* sink: name of target widget */
#define AIC3262_WIDGET_NAME 0
/* control: mixer control name */
#define AIC3262_CONTROL_NAME 1
/* source: name of source name */
#define AIC3262_SOURCE_NAME 2
/* D15..D8 aic3262 register offset */
#define AIC3262_REG_OFFSET_INDEX 0
/* D7...D0 register data */
#define AIC3262_REG_DATA_INDEX 1
/* Serial data bus uses I2S mode (Default mode) */
#define AIC3262_I2S_MODE 0x00
#define AIC3262_DSP_MODE 0x01
#define AIC3262_RIGHT_JUSTIFIED_MODE 0x02
#define AIC3262_LEFT_JUSTIFIED_MODE 0x03
/* 8 bit mask value */
#define AIC3262_8BITS_MASK 0xFF
/* shift value for CLK_REG_3 register */
#define CLK_REG_3_SHIFT 6
/* shift value for DAC_OSR_MSB register */
#define DAC_OSR_MSB_SHIFT 4
/* number of codec specific register for configuration */
#define NO_FEATURE_REGS 2
/* AIC3262 register space */
#define AIC3262_CACHEREGNUM 1024 /* Updated from 256 to support Page 3 registers */
#define DAC_FLAG 37
#define ADC_FLAG 36
#define DSP_NON_SYNC_MODE(state) (!( (state & 0x03) && (state & 0x30) ))
/*
*----------------------------------------------------------------------------
* @struct aic3262_setup_data |
* i2c specific data setup for AIC3262.
* @field unsigned short |i2c_address |
* Unsigned short for i2c address.
*----------------------------------------------------------------------------
*/
/*struct aic3262_setup_data {
unsigned short i2c_address;
};*/
struct aic3262_jack_data {
struct snd_soc_jack *jack;
int report;
struct switch_dev sdev;
};
/*configs |
* AIC3262 initialization data which has register offset and register
* value.
* @field u8 | book_no |
* AIC3262 Book Number Offsets required for initialization..
* @field u16 | reg_offset |
* AIC3262 Register offsets required for initialization..
* @field u8 | reg_val |
* value to set the AIC3262 register to initialize the AIC3262.
*----------------------------------------------------------------------------
*/
struct aic3262_priv {
u32 sysclk;
s32 master;
u8 book_no;
u8 page_no;
u8 process_flow;
u8 mute_codec;
u8 stream_status;
int current_dac_config[2];
int current_adc_config[2];
struct aic3262_jack_data hs_jack;
struct workqueue_struct *workqueue;
struct delayed_work delayed_work;
struct snd_soc_codec *codec;
struct mutex mutex;
struct mutex cfw_mutex;
struct cfw_state cfw_ps;
struct cfw_state *cfw_p;
struct aic3262_pdata *pdata;
int mute_asi; // Bit 0 -> ASI1, Bit 1-> ASI2, Bit 2 -> ASI3
int dsp_runstate;
const struct firmware *cur_fw;
int isdefault_fw;
};
/*struct aic3262_configs {
u8 book_no;
u16 reg_offset;
u8 reg_val;
};
*/
/*
*----------------------------------------------------------------------------
* @struct aic3262_rate_divs |
* Setting up the values to get different freqencies
*
* @field u32 | mclk |
* Master clock
* @field u32 | rate |
* sample rate
* @field u8 | p_val |
* value of p in PLL
* @field u32 | pll_j |
* value for pll_j
* @field u32 | pll_d |
* value for pll_d
* @field u32 | dosr |
* value to store dosr
* @field u32 | ndac |
* value for ndac
* @field u32 | mdac |
* value for mdac
* @field u32 | aosr |
* value for aosr
* @field u32 | nadc |
* value for nadc
* @field u32 | madc |
* value for madc
* @field u32 | blck_N |
* value for block N
* @field u32 | aic3262_configs |
* configurations for aic3262 register value
*----------------------------------------------------------------------------
*/
struct aic3262_rate_divs {
u32 mclk;
u32 rate;
u8 p_val;
u8 pll_j;
u16 pll_d;
u16 dosr;
u8 ndac;
u8 mdac;
u8 aosr;
u8 nadc;
u8 madc;
u8 blck_N;
// struct aic3262_configs codec_specific_regs[NO_FEATURE_REGS];
};
/*
*----------------------------------------------------------------------------
* @struct snd_soc_codec_dai |
* It is SoC Codec DAI structure which has DAI capabilities viz.,
* playback and capture, DAI runtime information viz. state of DAI
* and pop wait state, and DAI private data.
*----------------------------------------------------------------------------
*/
extern struct snd_soc_dai tlv320aic3262_dai;
/*
*----------------------------------------------------------------------------
nt aic3262_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value)
* @struct snd_soc_codec_device |
* This structure is soc audio codec device sturecute which pointer
* to basic functions aic3262_probe(), aic3262_remove(),
* aic3262_suspend() and aic3262_resume()
*
*/
extern struct snd_soc_codec_device soc_codec_dev_aic3262;
extern const aic3xxx_codec_ops aic3262_cfw_codec_ops;
void aic3262_hs_jack_detect(struct snd_soc_codec *codec,
struct snd_soc_jack *jack, int report);
unsigned int aic3262_read(struct snd_soc_codec *codec, unsigned int reg);
int aic3262_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value);
#endif /* _TLV320AIC3262_H */