| /* |
| * drivers/misc/tfa9887.c |
| * |
| * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. |
| * |
| * This software is licensed under the terms of the GNU General Public |
| * License version 2, as published by the Free Software Foundation, and |
| * may be copied, distributed, and modified under those terms. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| */ |
| |
| #include <linux/kernel.h> |
| #include <linux/init.h> |
| #include <linux/err.h> |
| #include <linux/module.h> |
| #include <linux/interrupt.h> |
| #include <linux/i2c.h> |
| #include <linux/regmap.h> |
| #include <linux/tfa9887.h> |
| #include <sound/initval.h> |
| #include <linux/sysfs.h> |
| #include <linux/miscdevice.h> |
| #include <linux/delay.h> |
| |
| #define STATUS_OK 0 |
| |
| void tegra_asoc_enable_clocks(void); |
| void tegra_asoc_disable_clocks(void); |
| |
| static ssize_t tfa9887_cal_show(struct kobject *kobj, |
| struct kobj_attribute *attr, char *buf); |
| |
| static ssize_t tfa9887_cal_store(struct kobject *kobj, |
| struct kobj_attribute *attr, const char *buf, size_t count); |
| |
| static ssize_t tfa9887_config_show(struct kobject *kobj, |
| struct kobj_attribute *attr, char *buf); |
| |
| static ssize_t tfa9887_config_store(struct kobject *kobj, |
| struct kobj_attribute *attr, const char *buf, size_t count); |
| |
| static ssize_t tfa9887_vol_show(struct kobject *kobj, |
| struct kobj_attribute *attr, char *buf); |
| |
| static ssize_t tfa9887_vol_store(struct kobject *kobj, |
| struct kobj_attribute *attr, const char *buf, size_t count); |
| |
| |
| static struct kobj_attribute tfa9887_config = |
| __ATTR(config, 0640, tfa9887_config_show, tfa9887_config_store); |
| |
| static struct kobj_attribute tfa9887_cal = |
| __ATTR(cal, 0640, tfa9887_cal_show, tfa9887_cal_store); |
| |
| static struct kobj_attribute tfa9887_vol = |
| __ATTR(vol, 0640, tfa9887_vol_show, tfa9887_vol_store); |
| |
| static struct kobject *tfa9887_kobj; |
| |
| static struct tfa9887_priv *tfa9887R, *tfa9887L, *tfa9887R_byte, *tfa9887L_byte; |
| |
| static int eq_mode, preset_mode, srate; |
| |
| static char calibdata[16]; |
| |
| static int calibration; |
| |
| static int recalibration; |
| |
| static int powerDown = 1; |
| |
| unsigned int volume_step[5] = {0, 2, 4, 6, 12}; |
| |
| /* begin binary data: */ |
| unsigned char coldpatch_data[] = {/* 10 */ |
| 0x08, 0x00, 0x70, 0x00, 0x07, 0x81, 0x00, 0x00, 0x00, 0x01 |
| }; |
| /* end binary data. size = 10 bytes */ |
| |
| /* begin binary data: */ |
| |
| /* begin binary data: */ |
| char n1d2_data[] = {/* 2380 */ |
| 0x03, 0x00, 0x70, 0x00, 0x01, 0xFB, 0x00, 0x71, 0x40 |
| , 0x00, 0x38, 0x08, 0x0A, 0x6F, 0x9B, 0xA6, 0x7D, 0x04, 0xB0, 0xB6, 0x62, 0x88, 0x69, 0x7E |
| , 0xC4, 0x08, 0x6A, 0xBF, 0x54, 0xFC, 0xB5, 0x00, 0x58, 0x7F, 0x3B, 0x80, 0x01, 0x25, 0x30 |
| , 0x50, 0x00, 0x80, 0x69, 0x5E, 0xD4, 0x3C, 0x3A, 0x90, 0x00, 0x0D, 0x72, 0x02, 0xC4, 0x80 |
| , 0x6A, 0xBE, 0xD4, 0x3E, 0x30, 0x40, 0x00, 0x80, 0x3B, 0x80, 0x01, 0x00, 0xB0, 0xB2, 0xF6 |
| , 0x48, 0x6A, 0x5E, 0x54, 0x3E, 0x3A, 0x80, 0x00, 0x80, 0x3B, 0x80, 0x01, 0x00, 0x9B, 0xA6 |
| , 0xF8, 0x49, 0x39, 0x84, 0x80, 0x80, 0x92, 0x19, 0xFE, 0x9C, 0x3B, 0x62, 0x40, 0x1C, 0x9B |
| , 0x84, 0x54, 0x3D, 0x61, 0x40, 0x7E, 0x9C, 0x3B, 0x80, 0x07, 0xF1, 0xA6, 0xB6, 0x7E, 0x9C |
| , 0x3B, 0x00, 0x40, 0x21, 0xB5, 0x00, 0x58, 0x3F, 0x3B, 0x80, 0x08, 0x00, 0x9B, 0xA4, 0x7E |
| , 0x9C, 0x9B, 0xA4, 0x54, 0x3D, 0xA5, 0xB2, 0xD8, 0x3F, 0xB5, 0x00, 0x42, 0xC0, 0x3C, 0xD8 |
| , 0x03, 0x00, 0x8B, 0x80, 0x7D, 0x7C, 0xB5, 0x00, 0x7E, 0x9C, 0x9B, 0x86, 0x7D, 0x04, 0x38 |
| , 0x0A, 0x0A, 0x6F, 0xB0, 0xB2, 0xD4, 0x7E, 0x6A, 0x7E, 0x52, 0xFD, 0x71, 0x04, 0xD8, 0x7F |
| , 0x3B, 0x80, 0x01, 0x25, 0x30, 0x50, 0x00, 0x80, 0x69, 0x5E, 0xD5, 0x3E, 0x72, 0x02, 0xC4 |
| , 0x11, 0x6A, 0xBE, 0xD4, 0xBC, 0x30, 0x40, 0x00, 0x80, 0x3B, 0x80, 0x01, 0x00, 0xB0, 0xB2 |
| , 0xF6, 0x00, 0xB5, 0x00, 0x54, 0x3C, 0x3A, 0x88, 0x00, 0x80, 0xB5, 0x00, 0x54, 0x3D, 0x3B |
| , 0x80, 0x01, 0x00, 0x9B, 0xA6, 0xFE, 0x9C, 0xB5, 0x00, 0x58, 0x3F, 0x3C, 0xD8, 0x03, 0x00 |
| , 0x8B, 0x80, 0x7D, 0x7C, 0xB5, 0x00, 0x7E, 0x9C, 0x3A, 0x88, 0x00, 0x0A, 0x9B, 0x8C, 0x42 |
| , 0x88, 0xA6, 0x56, 0x7D, 0x05, 0x39, 0x02, 0x22, 0x20, 0xFB, 0x00, 0x71, 0x40, 0x3E, 0xAA |
| , 0x08, 0xC4, 0x00, 0x3A, 0x89, 0x00, 0xA6, 0xBA, 0x41, 0x58, 0x7B, 0xB5, 0x00, 0x5C, 0x7D |
| , 0x3B, 0x80, 0x13, 0x20, 0xBA, 0x20, 0xDA, 0x7C, 0x6D, 0x5E, 0x50, 0xBD, 0x3A, 0x91, 0x00 |
| , 0x18, 0x82, 0x04, 0x7E, 0x50, 0x3A, 0x80, 0x00, 0x29, 0x3A, 0x9A, 0xFF, 0xFA, 0x38, 0x08 |
| , 0x0B, 0x68, 0x38, 0x0C, 0x0B, 0x6D, 0xBF, 0x10, 0x42, 0x40, 0x38, 0x0D, 0x0B, 0x6A, 0xBB |
| , 0x00, 0x4C, 0x98, 0x6A, 0x3E, 0xD5, 0xFC, 0x31, 0x80, 0x20, 0xAF, 0x3B, 0x80, 0x01, 0x07 |
| , 0x9B, 0xA2, 0xCA, 0x48, 0x7F, 0x4E, 0x54, 0xBC, 0xB5, 0x00, 0x4C, 0x88, 0x3A, 0x91, 0xFF |
| , 0x43, 0xB5, 0x00, 0x42, 0x90, 0x96, 0xF4, 0xD5, 0x3D, 0x3A, 0x81, 0xFF, 0x41, 0x61, 0x48 |
| , 0xFD, 0xA9, 0x3A, 0x88, 0x00, 0xAF, 0x61, 0x8A, 0x72, 0xE8, 0x6A, 0x7E, 0xC4, 0x00, 0x30 |
| , 0x40, 0x00, 0x80, 0x30, 0x70, 0x02, 0xBC, 0x3B, 0x80, 0x1C, 0x5A, 0xB5, 0x00, 0x55, 0x7C |
| , 0xB5, 0x00, 0x54, 0x3D, 0x3A, 0x88, 0x00, 0x0F, 0x62, 0x24, 0x44, 0x0A, 0x3A, 0x91, 0xFF |
| , 0x4F, 0x30, 0x50, 0x00, 0x80, 0x3B, 0x80, 0x01, 0x25, 0xB5, 0x00, 0x55, 0x7D, 0x6A, 0xDE |
| , 0x54, 0xBD, 0x3A, 0x81, 0xFF, 0xF3, 0x72, 0x22, 0xC2, 0x84, 0x30, 0xA0, 0x0A, 0x70, 0x61 |
| , 0x04, 0x42, 0x98, 0x7F, 0x2C, 0x76, 0x91, 0x38, 0x0C, 0x22, 0x08, 0x60, 0x08, 0x43, 0x48 |
| , 0x69, 0x3F, 0x54, 0x7D, 0xB5, 0x00, 0x52, 0xFF, 0x3B, 0x80, 0x1B, 0x5B, 0x38, 0x01, 0x0A |
| , 0x6F, 0x30, 0x00, 0x00, 0x20, 0xB9, 0x00, 0x54, 0x3D, 0x9B, 0x2B, 0x55, 0x3C, 0xB0, 0x04 |
| , 0x52, 0xBE, 0x38, 0x08, 0x22, 0x01, 0xA6, 0xD0, 0x52, 0x3F, 0x3A, 0x80, 0x00, 0x0F, 0x8B |
| , 0x80, 0x42, 0x50, 0x9B, 0xA2, 0x42, 0xC0, 0xFB, 0x00, 0x71, 0x40, 0x7C, 0x3A, 0x88, 0x00 |
| , 0xB4, 0xB5, 0x00, 0x53, 0x7C, 0x31, 0x1F, 0xFF, 0xE9, 0x69, 0x3F, 0x44, 0x0D, 0x3B, 0x80 |
| , 0x01, 0x25, 0xB5, 0x00, 0x54, 0xFD, 0x7F, 0x4E, 0x54, 0x3D, 0xB5, 0x00, 0x44, 0x00, 0x3B |
| , 0x80, 0x01, 0x25, 0x9B, 0xA7, 0x7E, 0x9C, 0x7D, 0x8C, 0x54, 0x3D, 0x7C, 0x24, 0xC4, 0x85 |
| , 0x6A, 0x3E, 0xD2, 0xBC, 0x61, 0x64, 0x44, 0x00, 0x3B, 0x80, 0x02, 0xE4, 0x30, 0x50, 0x00 |
| , 0x80, 0x9B, 0xA2, 0x52, 0x3E, 0x90, 0x90, 0xD4, 0xBD, 0xA2, 0x12, 0xFB, 0x24, 0xB5, 0x00 |
| , 0x4C, 0x8D, 0x3B, 0x44, 0x40, 0x7E, 0x31, 0x10, 0x00, 0x1C, 0xB5, 0x00, 0x4C, 0xCD, 0xB5 |
| , 0x00, 0x58, 0x3B, 0x3C, 0xD8, 0x03, 0x00, 0x8B, 0x80, 0x7D, 0x7B, 0xB5, 0x00, 0x7E, 0x9C |
| , 0x6C, 0x3F, 0xFD, 0x02, 0x3B, 0x80, 0x10, 0xA5, 0xB5, 0x00, 0x54, 0x7E, 0xB5, 0x00, 0x54 |
| , 0x3E, 0x3A, 0x90, 0x00, 0x5C, 0x30, 0x40, 0x00, 0x82, 0x7F, 0x28, 0xC2, 0x51, 0x3A, 0x9A |
| , 0xFF, 0xDE, 0x3A, 0xA3, 0x00, 0x14, 0x30, 0x41, 0x00, 0x00, 0x38, 0x10, 0x26, 0x91, 0x61 |
| , 0x2C, 0x7E, 0x50, 0x3A, 0x8C, 0xFF, 0xB3, 0x30, 0x05, 0x00, 0x00, 0x3B, 0x80, 0x0A, 0x71 |
| , 0xB5, 0x00, 0x40, 0x60, 0xB5, 0x00, 0x58, 0x3F, 0x3C, 0xD8, 0x03, 0x00, 0x8B, 0x80, 0x7D |
| , 0x7E, 0xB5, 0x00, 0x7E, 0x9C, 0x3C, 0xD0, 0x00, 0x8E, 0x3C, 0xCB, 0xFF, 0xB4, 0x82, 0x14 |
| , 0x52, 0xF6, 0x6C, 0x3C, 0xD4, 0x78, 0xB5, 0x00, 0x55, 0xFA, 0x3B, 0x46, 0x40, 0xB8, 0x95 |
| , 0xD4, 0xF9, 0x1A, 0xB5, 0x00, 0x53, 0x77, 0xB5, 0x00, 0x52, 0xB6, 0x3C, 0xC5, 0x40, 0xB7 |
| , 0x6A, 0x5C, 0x62, 0x0C, 0x61, 0x84, 0xFE, 0x9C, 0x7F, 0x20, 0xC3, 0x41, 0x3C, 0xC9, 0xFF |
| , 0x72, 0x30, 0xA0, 0x02, 0x17, 0xFB, 0x00, 0x71, 0x40, 0xBA, 0x9B, 0xA0, 0xE2, 0x0B, 0x9B |
| , 0xC0, 0xD6, 0x7B, 0x9B, 0x00, 0xD4, 0xFC, 0x8B, 0x80, 0x55, 0x7D, 0x30, 0xB0, 0x21, 0x2C |
| , 0x73, 0x05, 0xD3, 0xB7, 0xB5, 0x00, 0x52, 0x7F, 0x3B, 0x80, 0x01, 0xDA, 0x3A, 0x31, 0xFF |
| , 0xFE, 0x6A, 0x1E, 0x54, 0xBA, 0x7C, 0x01, 0x78, 0x4A, 0x6A, 0x7E, 0x52, 0xB7, 0x3B, 0x80 |
| , 0x01, 0x00, 0xB5, 0x00, 0x54, 0x7A, 0x9B, 0xC0, 0xD2, 0xBF, 0x90, 0x94, 0xD5, 0x3D, 0x3A |
| , 0x92, 0x00, 0x04, 0x92, 0x11, 0xD5, 0xBE, 0x6A, 0x1E, 0x54, 0xBA, 0x3A, 0x9B, 0x00, 0x05 |
| , 0x7C, 0x27, 0x78, 0x06, 0xB5, 0x00, 0x55, 0x7D, 0x3B, 0x44, 0x40, 0xBF, 0x80, 0x18, 0x54 |
| , 0x7A, 0x80, 0xB8, 0x54, 0xFC, 0xB5, 0x00, 0x52, 0xB6, 0x82, 0x14, 0x7E, 0x9C, 0x3B, 0x46 |
| , 0x40, 0xDE, 0x6A, 0x5D, 0xD4, 0x38, 0x3C, 0xC5, 0x40, 0xDB, 0xB5, 0x00, 0x43, 0x0B, 0x94 |
| , 0x18, 0xFE, 0x9C, 0xB5, 0x00, 0x43, 0x0B, 0x94, 0x18, 0xC0, 0x41, 0x3B, 0x00, 0x40, 0xDF |
| , 0xB5, 0x00, 0x58, 0x39, 0xB5, 0x00, 0x58, 0x39, 0x3C, 0xD8, 0x03, 0x00, 0x8B, 0x80, 0x7E |
| , 0x9C, 0x3C, 0xD0, 0xFF, 0x72, 0x71, 0x65, 0x7D, 0x2B, 0x6A, 0x7B, 0x42, 0x91, 0x6A, 0xBB |
| , 0xE2, 0x4B, 0x6A, 0x3D, 0x52, 0xF8, 0xB5, 0x00, 0x58, 0x7B, 0x3B, 0x80, 0x16, 0x94, 0xB5 |
| , 0x00, 0x54, 0xF9, 0x7C, 0x44, 0xD4, 0xB8, 0x6A, 0x1B, 0xC2, 0x91, 0x61, 0xC0, 0x7E, 0x9C |
| , 0x6A, 0xBE, 0x54, 0xB6, 0x3B, 0x80, 0x00, 0xA9, 0x9B, 0xC3, 0x62, 0x09, 0x6A, 0xDB, 0xD4 |
| , 0x3C, 0x3A, 0x90, 0x00, 0x25, 0x61, 0xCC, 0x42, 0x80, 0x6A, 0xBE, 0x54, 0xBA, 0x3B, 0x80 |
| , 0x00, 0xA9, 0x9B, 0xC3, 0x62, 0x09, 0x9B, 0xA0, 0xD4, 0x37, 0x3A, 0x88, 0x00, 0x96, 0x66 |
| , 0x04, 0x45, 0x0A, 0xFB, 0x00, 0x71, 0x40, 0xF8, 0x3A, 0x99, 0xFF, 0x6B, 0xB5, 0x00, 0x72 |
| , 0x81, 0x80, 0x18, 0x43, 0x80, 0x6A, 0xFE, 0xD4, 0xBA, 0x3B, 0x80, 0x02, 0x8F, 0x80, 0xD4 |
| , 0x62, 0x09, 0x7F, 0x4E, 0x54, 0xBD, 0xB5, 0x00, 0x43, 0x08, 0x38, 0x10, 0x00, 0xCF, 0x3B |
| , 0x80, 0x01, 0x33, 0x9B, 0xA2, 0x74, 0x56, 0x7F, 0x4E, 0x55, 0x3D, 0xB5, 0x00, 0x43, 0x10 |
| , 0x3A, 0x82, 0x00, 0xC7, 0x7A, 0x2B, 0x54, 0x7D, 0x30, 0xA0, 0x12, 0x00, 0x30, 0xB0, 0x0B |
| , 0x66, 0x30, 0x50, 0x00, 0x80, 0x3B, 0x80, 0x02, 0xBE, 0xB5, 0x00, 0x62, 0x09, 0x7F, 0x4E |
| , 0x55, 0x3C, 0xB5, 0x00, 0x43, 0x10, 0x90, 0xDB, 0x54, 0xBD, 0x61, 0x44, 0x7E, 0x9C, 0xA2 |
| , 0x17, 0x55, 0x39, 0x3A, 0x92, 0x00, 0xC8, 0x3A, 0x89, 0xFF, 0xBE, 0x3B, 0x43, 0x41, 0x49 |
| , 0x6A, 0xBF, 0x54, 0xFD, 0x38, 0x12, 0x0B, 0x66, 0x30, 0x60, 0x00, 0x80, 0x30, 0x80, 0x12 |
| , 0x00, 0x30, 0xA0, 0x01, 0x80, 0x3B, 0x80, 0x01, 0x1C, 0xB5, 0x00, 0x61, 0x46, 0xB5, 0x00 |
| , 0x54, 0xB9, 0x30, 0x80, 0x01, 0x00, 0x30, 0x50, 0x01, 0x00, 0x30, 0x70, 0x00, 0x80, 0x3B |
| , 0x80, 0x1C, 0x3E, 0x38, 0x0C, 0x0B, 0x6B, 0x30, 0x90, 0x01, 0x80, 0x38, 0x0A, 0x22, 0x01 |
| , 0x20, 0x80, 0x41, 0x28, 0x30, 0xA0, 0x01, 0x00, 0xB5, 0x00, 0x42, 0x11, 0xB5, 0x00, 0x43 |
| , 0x08, 0xD4, 0xC8, 0x42, 0x11, 0x60, 0x24, 0xFE, 0x9C, 0x30, 0x90, 0x01, 0x00, 0x30, 0x50 |
| , 0x00, 0x80, 0x30, 0xA0, 0x22, 0x29, 0x3B, 0x80, 0x02, 0x60, 0x30, 0x80, 0x01, 0x80, 0x30 |
| , 0x80, 0x01, 0x00, 0x30, 0x50, 0x00, 0x80, 0x3B, 0x80, 0x00, 0xC1, 0x30, 0x90, 0x01, 0x00 |
| , 0x30, 0x90, 0x01, 0x00, 0xB5, 0x00, 0x78, 0x09, 0x30, 0x50, 0x00, 0x3F, 0x3B, 0x80, 0x00 |
| , 0x51, 0xFB, 0x00, 0x71, 0x41, 0x36, 0xB5, 0x00, 0x54, 0x7F, 0x38, 0x0A, 0x0B, 0x60, 0xD0 |
| , 0x0C, 0x54, 0x3F, 0x30, 0x60, 0x00, 0x3F, 0x3B, 0x80, 0x00, 0x7A, 0xB5, 0x00, 0x61, 0x40 |
| , 0x9B, 0xA8, 0x74, 0x55, 0xA5, 0xF2, 0xE2, 0x09, 0x38, 0x09, 0x0B, 0x69, 0x38, 0x0A, 0x0B |
| , 0x61, 0x38, 0x0C, 0x0A, 0x7C, 0x30, 0xA0, 0x0B, 0x67, 0x3B, 0x80, 0x00, 0x89, 0x9B, 0xE0 |
| , 0xD3, 0xD5, 0x38, 0x0C, 0x0B, 0x67, 0x9B, 0xA8, 0x54, 0xBD, 0xA6, 0x1A, 0xFE, 0x9C, 0x3B |
| , 0x00, 0x41, 0x4A, 0x38, 0x01, 0x0B, 0x69, 0x9B, 0xA8, 0x54, 0xBD, 0x61, 0x84, 0x7E, 0x9C |
| , 0x92, 0x1B, 0xFE, 0x9C, 0x3B, 0x63, 0x41, 0x52, 0x38, 0x08, 0x0B, 0x6C, 0x9B, 0xDF, 0xD4 |
| , 0xBE, 0xA5, 0xB2, 0xC3, 0x48, 0x38, 0x0B, 0x0B, 0x67, 0x38, 0x09, 0x0B, 0x69, 0x3B, 0x80 |
| , 0x41, 0xD0, 0xB5, 0x00, 0x7E, 0x9C, 0x7F, 0x4E, 0x54, 0xBD, 0xB5, 0x00, 0x42, 0x88, 0x3A |
| , 0x91, 0xFF, 0x7A, 0x31, 0x20, 0x00, 0xC8, 0x82, 0x14, 0x44, 0x95, 0x3B, 0x44, 0x41, 0x60 |
| , 0x38, 0x0A, 0x0B, 0x6A, 0x3A, 0x81, 0x00, 0x29, 0x38, 0x0C, 0x0B, 0x69, 0x38, 0x0E, 0x0B |
| , 0x62, 0xA2, 0x1B, 0xFE, 0x9C, 0x3B, 0x66, 0x41, 0x6F, 0x38, 0x0C, 0x0A, 0x7A, 0xA2, 0x13 |
| , 0x7E, 0x9C, 0x3B, 0x64, 0x41, 0x6F, 0x38, 0x0C, 0x0A, 0x79, 0xA2, 0x13, 0x7E, 0x9C, 0x3B |
| , 0x67, 0x41, 0x6F, 0x38, 0x0C, 0x0B, 0x63, 0xD0, 0x35, 0x54, 0xB9, 0x3A, 0x89, 0x00, 0x50 |
| , 0xB5, 0x00, 0x1A, 0x61, 0x38, 0x00, 0x0B, 0x68, 0x95, 0xD8, 0xC0, 0x40, 0xB3, 0xB7, 0x7E |
| , 0x9C, 0x3B, 0x00, 0x41, 0x76, 0x38, 0x0B, 0x0B, 0x6A, 0x38, 0x0C, 0x0B, 0x64, 0xD0, 0x34 |
| , 0x54, 0xBE, 0x38, 0x0A, 0x0B, 0x65, 0x9B, 0x1F, 0xE1, 0x80, 0x95, 0xD8, 0xFE, 0x40, 0xFB |
| , 0x00, 0x71, 0x41, 0x74, 0xB2, 0xB7, 0x40, 0x48, 0x38, 0x0B, 0x0B, 0x6A, 0x61, 0x08, 0x54 |
| , 0xBC, 0xB5, 0x00, 0x43, 0x08, 0xA2, 0x13, 0x54, 0x3E, 0x3A, 0x92, 0xFF, 0x94, 0x3B, 0x46 |
| , 0x41, 0x7E, 0x3A, 0x89, 0xFF, 0xEB, 0x9B, 0xBF, 0xD4, 0xFC, 0xB5, 0x00, 0x42, 0xC0, 0xB5 |
| , 0x00, 0x42, 0x90, 0x3A, 0x8A, 0xFF, 0xA5, 0x82, 0x14, 0x7E, 0x9C, 0x3B, 0x43, 0x41, 0x91 |
| , 0x6A, 0x7B, 0xD5, 0x37, 0x3A, 0x8A, 0x00, 0x95, 0x31, 0x1F, 0xFF, 0x6A, 0x9B, 0xA0, 0xCC |
| , 0x0D, 0x6A, 0x7E, 0xC3, 0x90, 0x6A, 0x1B, 0x72, 0x81, 0xB5, 0x00, 0x74, 0x56, 0x30, 0xA0 |
| , 0x0E, 0xBA, 0x3B, 0x80, 0x02, 0x8F, 0x80, 0x18, 0x61, 0x85, 0x6A, 0x5D, 0x55, 0x3D, 0x3B |
| , 0x80, 0x1A, 0x0A, 0x3C, 0xC8, 0xFF, 0xD6, 0x3B, 0x00, 0x41, 0x92, 0xB5, 0x00, 0x54, 0xBC |
| , 0xB5, 0x00, 0x54, 0xBC, 0x61, 0x44, 0x7E, 0x9C, 0x98, 0xB5, 0x7E, 0x9C, 0x82, 0x14, 0x7E |
| , 0x9C, 0x3B, 0x62, 0x41, 0xA3, 0x6A, 0x9C, 0x54, 0xB9, 0x3A, 0x81, 0x00, 0x14, 0x3A, 0x8A |
| , 0x00, 0x22, 0x61, 0x40, 0x43, 0x08, 0x3A, 0x90, 0xFF, 0xED, 0xD0, 0x4C, 0x43, 0x10, 0xB5 |
| , 0x00, 0x54, 0xB6, 0x94, 0x03, 0xE2, 0x09, 0x30, 0xA0, 0x07, 0xA1, 0x3B, 0x80, 0x00, 0x14 |
| , 0xB5, 0x00, 0x61, 0x40, 0x3B, 0x00, 0x41, 0xA4, 0xB5, 0x00, 0x55, 0xB7, 0xB5, 0x00, 0x55 |
| , 0xB7, 0x3A, 0x83, 0x00, 0x97, 0x9B, 0xA0, 0xC5, 0x04, 0x31, 0x0F, 0xFF, 0x6A, 0x7F, 0x4E |
| , 0x4C, 0x05, 0xB5, 0x00, 0x72, 0x81, 0x80, 0x18, 0x43, 0x98, 0x6A, 0x3B, 0xD4, 0xB6, 0x3B |
| , 0x80, 0x02, 0x8F, 0x80, 0xD4, 0x62, 0x09, 0x6A, 0x5D, 0x55, 0x37, 0xB5, 0x00, 0x54, 0x36 |
| , 0x3B, 0x80, 0x17, 0x99, 0xB5, 0x00, 0x7E, 0x9C, 0x8B, 0x80, 0x54, 0xB7, 0xFB, 0x00, 0x71 |
| , 0x41, 0xB2, 0x3A, 0x89, 0x00, 0x5C, 0x3A, 0x91, 0xFF, 0xF2, 0x60, 0x00, 0x78, 0x11, 0x38 |
| , 0x0A, 0x0B, 0x6A, 0xB5, 0x00, 0x4A, 0x10, 0xB3, 0x02, 0xC3, 0x08, 0x90, 0xDB, 0xCA, 0x50 |
| , 0x3A, 0x98, 0x00, 0x10, 0xB2, 0xD3, 0x42, 0x98, 0x92, 0x17, 0xC3, 0x48, 0xB5, 0x00, 0x48 |
| , 0x40, 0x3B, 0x42, 0x41, 0xCD, 0xB5, 0x00, 0x55, 0x39, 0x3A, 0x9A, 0x00, 0x5D, 0xB5, 0x00 |
| , 0x43, 0x18, 0x82, 0x18, 0x7E, 0x9C, 0x3B, 0x66, 0x41, 0xCD, 0x3A, 0x8A, 0x00, 0x5E, 0xB5 |
| , 0x00, 0x43, 0x08, 0x90, 0xD8, 0xFE, 0x9C, 0xA2, 0x1A, 0xC3, 0x48, 0x3B, 0x66, 0x41, 0xCB |
| , 0x6C, 0x1D, 0xFE, 0x4A, 0x3B, 0x00, 0x41, 0xCE, 0xB5, 0x00, 0x7E, 0x48, 0x3B, 0x00, 0x41 |
| , 0xCE, 0xB5, 0x00, 0x58, 0x3B, 0xB5, 0x00, 0x58, 0x3B, 0x3C, 0xD8, 0x03, 0x00, 0x7F, 0x4E |
| , 0x7D, 0x55, 0x39, 0x84, 0x80, 0x02, 0x39, 0x86, 0x80, 0x02, 0x30, 0x40, 0x01, 0x00, 0xA8 |
| , 0x1E, 0x7E, 0x9C, 0xA2, 0x02, 0x7E, 0x9C, 0x3B, 0x43, 0x41, 0xDA, 0x30, 0x10, 0x01, 0xFF |
| , 0xA8, 0x38, 0xFE, 0x9C, 0x30, 0x4F, 0xFE, 0x00, 0xA9, 0x26, 0x7E, 0x9C, 0x3C, 0xD8, 0x03 |
| , 0x00, 0x9B, 0x99, 0x7E, 0x9C, 0xA0, 0x86, 0x7E, 0x9C, 0x3A, 0x89, 0x00, 0xC7, 0x7E, 0x81 |
| , 0xC2, 0x88, 0x3A, 0x89, 0xFF, 0xE9, 0x6A, 0x3F, 0x54, 0xFD, 0xB5, 0x00, 0x58, 0x7F, 0x30 |
| , 0x60, 0x00, 0x80, 0x3B, 0x80, 0x00, 0xB6, 0xB8, 0xA2, 0xE2, 0x48, 0xB5, 0x00, 0x54, 0xBE |
| , 0x38, 0x20, 0x0A, 0x6F, 0xB5, 0x00, 0x76, 0x88, 0x30, 0x62, 0x00, 0x00, 0xB5, 0x00, 0x42 |
| , 0x90, 0xA0, 0xB7, 0x55, 0xBD, 0xB5, 0x00, 0x42, 0xD0, 0x38, 0x0C, 0x22, 0x13, 0xB5, 0x00 |
| , 0x42, 0x98, 0xD0, 0x35, 0x7E, 0x9C, 0x3A, 0x83, 0xFF, 0x57, 0x3F, 0x00, 0x71, 0x41, 0xF0 |
| , 0xB5, 0x00, 0x18, 0x61, 0x3A, 0x90, 0x00, 0x9B, 0xD0, 0x4C, 0x62, 0x09, 0x30, 0x70, 0x00 |
| , 0x80, 0xB5, 0x00, 0x55, 0x7D, 0x3B, 0x80, 0x00, 0xA9, 0x9B, 0xC6, 0x61, 0x40, 0x7F, 0x4E |
| , 0x54, 0xBD, 0x6A, 0x1F, 0x4C, 0x08, 0x3B, 0x80, 0x01, 0x0E, 0x30, 0x50, 0x00, 0x80, 0xB5 |
| , 0x00, 0x58, 0x3F, 0x3C, 0xD8, 0x03, 0x00, 0x8B, 0x80, 0x7D, 0x7D, 0xB5, 0x00, 0x7E, 0x9C |
| , 0x03, 0x00, 0x70, 0x00, 0x03, 0x21, 0x00, 0x71, 0x0A, 0x6F, 0x00, 0x00, 0x01, 0x00, 0x00 |
| , 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00 |
| , 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x2D, 0x00, 0x71, 0x0B, 0x60 |
| , 0x00, 0xB8, 0x45, 0x7F, 0xEA, 0x29, 0x00, 0x00, 0x07, 0x40, 0x0F, 0x26, 0x3F, 0xFF, 0x9F |
| , 0x02, 0xCC, 0xCD, 0x00, 0x12, 0x00, 0x40, 0x00, 0x00, 0x01, 0x47, 0xAE, 0x00, 0x00, 0x00 |
| , 0x02, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x0F, 0x00, 0x71 |
| , 0x0A, 0x79, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x7E, 0x4D, 0xFE, 0x03 |
| , 0x00, 0x70, 0x00, 0x05, 0x03, 0x00, 0x70, 0x00, 0x07, 0x7B, 0x00, 0x71, 0x03, 0x00, 0x00 |
| , 0x00, 0x01, 0x00, 0x0B, 0x23, 0x00, 0x40, 0x00, 0x00, 0x3B, 0x80, 0x00, 0x00, 0x01, 0x00 |
| , 0x0B, 0xAB, 0x00, 0x40, 0x24, 0x00, 0x3B, 0x80, 0x00, 0x00, 0x01, 0x00, 0x0D, 0xF5, 0x00 |
| , 0x40, 0x3A, 0x00, 0x3B, 0x80, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x6B, 0x00, 0x40, 0x97, 0x00 |
| , 0x3B, 0x80, 0x00, 0x00, 0x01, 0x00, 0x05, 0xC6, 0x00, 0x40, 0xAB, 0x00, 0x3B, 0x80, 0x00 |
| , 0x00, 0x01, 0x00, 0x0D, 0x24, 0x00, 0x40, 0xE2, 0x00, 0x3B, 0x80, 0x00, 0x00, 0x01, 0x00 |
| , 0x12, 0x3A, 0x00, 0x7E, 0x9C, 0x00, 0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x7B, 0x00 |
| , 0x41, 0xD0, 0x00, 0x3B, 0x80, 0x00, 0x00, 0x01, 0x00, 0x1B, 0xA7, 0x00, 0x41, 0xDD, 0x00 |
| , 0x3B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03 |
| , 0x00, 0x70, 0x00, 0x00, 0x23, 0x00, 0x70, 0x00, 0x02, 0x00, 0x01, 0x00, 0x80, 0x03, 0xFF |
| , 0xFF, 0xF9, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xF6, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x1B, 0x00 |
| , 0x00, 0x1B, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x1C, 0x03, 0x00, 0x70, 0x01 |
| , 0x12 |
| }; |
| /* end binary data. size = 2380bytes */ |
| |
| /* begin binary data: */ |
| char speaker_data[] = {/* 423 */ |
| 0x00, 0x00, 0xD1, 0xFF, 0xFE, 0x06, 0xFF, 0xFE, 0x55, 0x00, 0x03, 0x2F, 0xFF, 0xFA, 0xF9 |
| , 0x00, 0x05, 0x77, 0xFF, 0xFC, 0x89, 0xFF, 0xFC, 0x9A, 0x00, 0x00, 0x0B, 0xFF, 0xFA, 0x84 |
| , 0x00, 0x02, 0x39, 0xFF, 0xFA, 0xD6, 0x00, 0x02, 0x98, 0xFF, 0xFC, 0xF7, 0x00, 0x00, 0xFE |
| , 0xFF, 0xFB, 0xD6, 0xFF, 0xFF, 0x47, 0x00, 0x02, 0x0A, 0xFF, 0xFD, 0x0F, 0x00, 0x01, 0x40 |
| , 0xFF, 0xFD, 0xE5, 0xFF, 0xFE, 0x9D, 0xFF, 0xFE, 0xD6, 0xFF, 0xFE, 0x68, 0xFF, 0xFD, 0x59 |
| , 0xFF, 0xFE, 0xAB, 0xFF, 0xFE, 0x65, 0x00, 0x00, 0x2E, 0xFF, 0xFB, 0x78, 0xFF, 0xFF, 0x2C |
| , 0x00, 0x00, 0x28, 0xFF, 0xFA, 0x9D, 0x00, 0x01, 0x7D, 0xFF, 0xFC, 0x9E, 0xFF, 0xFC, 0x0C |
| , 0x00, 0x01, 0x97, 0xFF, 0xF9, 0x25, 0x00, 0x00, 0xA5, 0xFF, 0xFC, 0x5B, 0xFF, 0xFF, 0x1B |
| , 0x00, 0x01, 0xCE, 0xFF, 0xF9, 0xE0, 0x00, 0x03, 0x9B, 0x00, 0x00, 0x98, 0xFF, 0xFC, 0x5D |
| , 0x00, 0x01, 0x7A, 0xFF, 0xFA, 0x43, 0xFF, 0xFF, 0x82, 0xFF, 0xFF, 0x66, 0xFF, 0xF8, 0xD6 |
| , 0xFF, 0xFD, 0xE7, 0x00, 0x01, 0x04, 0xFF, 0xF7, 0xF3, 0xFF, 0xFE, 0x79, 0xFF, 0xFD, 0x5B |
| , 0xFF, 0xFB, 0xC4, 0xFF, 0xFE, 0xF5, 0xFF, 0xFA, 0x9B, 0xFF, 0xFF, 0x87, 0xFF, 0xFB, 0xC1 |
| , 0xFF, 0xFD, 0xF3, 0x00, 0x00, 0x12, 0x00, 0x01, 0x8C, 0xFF, 0xF6, 0x37, 0x00, 0x05, 0x49 |
| , 0xFF, 0xFA, 0x1F, 0xFF, 0xFC, 0x9E, 0x00, 0x00, 0xD8, 0xFF, 0xF7, 0x74, 0xFF, 0xFE, 0x29 |
| , 0xFF, 0xFD, 0x42, 0xFF, 0xF3, 0x14, 0x00, 0x02, 0x1B, 0xFF, 0xF5, 0x86, 0xFF, 0xF7, 0x64 |
| , 0xFF, 0xF6, 0x6D, 0xFF, 0xF3, 0x81, 0x00, 0x00, 0x2F, 0xFF, 0xF0, 0x35, 0xFF, 0xFC, 0xFA |
| , 0x00, 0x03, 0x5E, 0xFF, 0xF9, 0xA2, 0x00, 0x09, 0x46, 0xFF, 0xFE, 0x88, 0x00, 0x09, 0x61 |
| , 0x00, 0x04, 0x3E, 0x00, 0x07, 0x57, 0x00, 0x09, 0xA2, 0xFF, 0xFD, 0x53, 0x00, 0x10, 0xD6 |
| , 0xFF, 0xF7, 0xEE, 0xFF, 0xFC, 0xDC, 0x00, 0x04, 0x42, 0xFF, 0xF4, 0x9B, 0xFF, 0xF4, 0xA3 |
| , 0xFF, 0xF0, 0x54, 0xFF, 0xF0, 0x30, 0xFF, 0xFB, 0x3B, 0xFF, 0xF2, 0x47, 0x00, 0x0E, 0xBA |
| , 0xFF, 0xF7, 0x96, 0x00, 0x22, 0x85, 0x00, 0x13, 0xA9, 0x00, 0x57, 0x54, 0x00, 0x13, 0x9B |
| , 0x00, 0x69, 0xD8, 0x00, 0x2B, 0xD5, 0x00, 0x73, 0x6B, 0x00, 0x40, 0x09, 0x00, 0x40, 0x8E |
| , 0xFF, 0xD6, 0x1D, 0xFF, 0xEA, 0x06, 0xFF, 0xB0, 0xD7, 0xFF, 0x5F, 0x5B, 0xFF, 0xA0, 0xAA |
| , 0x07, 0x36, 0x2D, 0xFF, 0xAA, 0xA7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0xCC, 0xCD |
| , 0x66, 0x66, 0x66, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x19, 0x99, 0x9A |
| , 0x00, 0x01, 0x76, 0x00, 0x01, 0x77, 0x04, 0x00, 0x00, 0x00, 0x67, 0xAE, 0x1C, 0xC0, 0x00 |
| , 0x00, 0x6F, 0x69 |
| }; |
| /* end binary data. size = 423 bytes */ |
| |
| /* begin binary data: */ |
| char config_data[] = {/* 165 */ |
| 0x09, 0xF3, 0x33, 0x01, 0x3E, 0x66, 0x00, 0x54, 0xCD, 0x00, 0x00, 0x14, 0x00, 0x00, 0x02 |
| , 0x1A, 0xE6, 0x40, 0x1B, 0x40, 0xD4, 0x1C, 0x59, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x4B, 0x00, 0x01, 0x4B |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01 |
| , 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x80, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x47 |
| , 0x01, 0x47, 0xAE, 0x00, 0x19, 0x9A, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xCD, 0x02, 0x80, 0x00 |
| , 0x00, 0x00, 0x01, 0x05, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0x50, 0x00, 0x00 |
| , 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x19, 0x9A, 0x00, 0x00, 0x80, 0x00, 0x00, 0x02 |
| , 0x00, 0x00, 0x01, 0x01, 0x47, 0xAE, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x19, 0x99, 0x9A |
| , 0x00, 0x80, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x30, 0x00, 0x00, 0x02, 0x00, 0x00, 0x18 |
| , 0xEC, 0x00, 0x00, 0x00, 0x03, 0xD7, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00 |
| }; |
| /* end binary data. size = 165 bytes */ |
| |
| /* begin binary data: */ |
| char eq_data_hand[] = {/* 180 */ |
| 0x00, 0x00, 0x01, 0xC2, 0x90, 0xA8, 0x7D, 0x5E, 0x28, 0x3E, 0xB3, 0x60, 0x82, 0x99, 0x40 |
| , 0x3E, 0xB3, 0x60, 0x00, 0x00, 0x01, 0xC2, 0x90, 0xA8, 0x7D, 0x5E, 0x28, 0x3E, 0xB3, 0x60 |
| , 0x82, 0x99, 0x40, 0x3E, 0xB3, 0x60, 0x00, 0x00, 0x01, 0xC8, 0xCF, 0x48, 0x76, 0x89, 0x90 |
| , 0x34, 0xDC, 0x58, 0x89, 0xF4, 0xCC, 0x42, 0xD2, 0xBC, 0x00, 0x00, 0x01, 0xEE, 0x00, 0x24 |
| , 0x31, 0xEB, 0x08, 0x29, 0x55, 0x8C, 0x8C, 0x6F, 0x80, 0x6A, 0x4F, 0xC8, 0x00, 0x00, 0x01 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 |
| , 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| , 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| , 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 |
| }; |
| /* end binary data. size = 180 bytes */ |
| |
| /* begin binary data: */ |
| char eq_data_table[] = {/* 180 */ |
| 0x00, 0x00, 0x01, 0xC2, 0x90, 0xA8, 0x7D, 0x5E, 0x28, 0x3E, 0xB3, 0x60, 0x82, 0x99, 0x40 |
| , 0x3E, 0xB3, 0x60, 0x00, 0x00, 0x01, 0xC2, 0x90, 0xA8, 0x7D, 0x5E, 0x28, 0x3E, 0xB3, 0x60 |
| , 0x82, 0x99, 0x40, 0x3E, 0xB3, 0x60, 0x00, 0x00, 0x01, 0xC8, 0xCF, 0x48, 0x76, 0x89, 0x90 |
| , 0x36, 0x25, 0x30, 0x89, 0xA7, 0x50, 0x41, 0x3C, 0x6C, 0x00, 0x00, 0x01, 0xEE, 0x00, 0x24 |
| , 0x31, 0xEB, 0x08, 0x29, 0x55, 0x8C, 0x8C, 0x6F, 0x80, 0x6A, 0x4F, 0xC8, 0x00, 0x00, 0x01 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 |
| , 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| , 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| , 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00 |
| }; |
| |
| /* end binary data. size = 180 bytes */ |
| |
| /* begin binary data: */ |
| char preset_data0[] = {/* 87 */ |
| 0x00, 0x00, 0x07, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x40 |
| , 0x00, 0x00, 0x00, 0x00, 0x01, 0x2C, 0x01, 0x47, 0xAE, 0x00, 0x2B, 0xB1, 0x00, 0x00, 0x9D |
| , 0x00, 0x0D, 0x1B, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x08, 0x00, 0x00 |
| , 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0C, 0xCD, 0x00, 0x40, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x48, 0x00, 0x01, 0x48 |
| , 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0xCD, 0x00, 0x00, 0x03 |
| }; |
| /* end binary data. size = 87 bytes */ |
| |
| /* begin binary data: */ |
| char preset_data1[] = {/* 87 */ |
| 0x00, 0x00, 0x07, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x40 |
| , 0x00, 0x00, 0x00, 0x00, 0x01, 0x2C, 0x01, 0x47, 0xAE, 0x00, 0x2B, 0xB1, 0x00, 0x00, 0x9D |
| , 0x00, 0x0D, 0x1B, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00 |
| , 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0C, 0xCD, 0x00, 0x40, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x48, 0x00, 0x01, 0x48 |
| , 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0xCD, 0x00, 0x00, 0x03 |
| }; |
| /* end binary data. size = 87 bytes */ |
| |
| char preset_data2[] = {/* 87 */ |
| 0x00, 0x00, 0x07, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x40 |
| , 0x00, 0x00, 0x00, 0x00, 0x01, 0x2C, 0x01, 0x47, 0xAE, 0x00, 0x2B, 0xB1, 0x00, 0x00, 0x9D |
| , 0x00, 0x0D, 0x1B, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x08, 0x00, 0x00 |
| , 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0C, 0xCD, 0x00, 0x40, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x48, 0x00, 0x01, 0x48 |
| , 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0xCD, 0x00, 0x00, 0x03 |
| }; |
| /* end binary data. size = 87 bytes */ |
| |
| /* begin binary data: */ |
| char preset_data3[] = {/* 87 */ |
| 0x00, 0x00, 0x07, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x40 |
| , 0x00, 0x00, 0x00, 0x00, 0x01, 0x2C, 0x01, 0x47, 0xAE, 0x00, 0x2B, 0xB1, 0x00, 0x00, 0x9D |
| , 0x00, 0x0D, 0x1B, 0x01, 0x00, 0x00, 0x01, 0x80, 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00 |
| , 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0C, 0xCD, 0x00, 0x40, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x48, 0x00, 0x01, 0x48 |
| , 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0xCD, 0x00, 0x00, 0x03 |
| }; |
| /* end binary data. size = 87 bytes */ |
| |
| /* begin binary data: */ |
| char preset_data4[] = {/* 87 */ |
| 0x00, 0x00, 0x07, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x40 |
| , 0x00, 0x00, 0x00, 0x00, 0x01, 0x2C, 0x01, 0x47, 0xAE, 0x00, 0x2B, 0xB1, 0x00, 0x00, 0x9D |
| , 0x00, 0x0D, 0x1B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x08, 0x00, 0x00 |
| , 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x0C, 0xCD, 0x00, 0x40, 0x00 |
| , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x48, 0x00, 0x01, 0x48 |
| , 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0C, 0xCD, 0x00, 0x00, 0x03 |
| }; |
| /* end binary data. size = 87 bytes */ |
| |
| void convertBytes2Data(int num_bytes, const unsigned char bytes[], int data[]) |
| { |
| int i; /* index for data */ |
| int k; /* index for bytes */ |
| int d; |
| int num_data = num_bytes/3; |
| |
| for (i = 0, k = 0; i < num_data; ++i, k += 3) { |
| d = (bytes[k] << 16) | (bytes[k+1] << 8) | (bytes[k+2]); |
| if (bytes[k] & 0x80) {/* sign bit was set*/ |
| d = - ((1<<24)-d); |
| } |
| data[i] = d; |
| } |
| } |
| |
| int ProcessPatchFile(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte, int length, const unsigned char* bytes) |
| { |
| unsigned int size; |
| int index = 0; |
| unsigned char buffer[MAX_I2C_LENGTH]; |
| int error; |
| int value = 0; |
| unsigned int status; |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &status); |
| if (error == Tfa9887_Error_Ok) { |
| if ( (status & 0x0043) != 0x0043) { |
| /* one of Vddd, PLL and clocks not ok */ |
| error = -1; |
| } |
| } |
| //pr_info("tfa status %u\n",status); |
| error = DspReadMem(tfa9887, tfa9887_byte, 0x2210, 1, &value); |
| //pr_info("tfa Version %x\n",value); |
| while (index < length) { |
| /* extract little endian length */ |
| size = bytes[index] + bytes[index+1] * 256; |
| index += 2; |
| if ( (index + size) > length) { |
| /* too big, outside the buffer, error in the input data */ |
| return -1; |
| } |
| memcpy(buffer, bytes + index, size); |
| error = regmap_raw_write(tfa9887_byte->regmap, buffer[0], &buffer[1] , (size -1)); |
| //pr_info("%d %d\n",buffer[0],size -1); |
| if (error != Tfa9887_Error_Ok) { |
| pr_info("ProcessPatchFile error\n"); |
| break; |
| } |
| index += size; |
| } |
| return error; |
| } |
| |
| int DspReadMem(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte, unsigned short start_offset, int num_words, int *pValues) |
| { |
| unsigned int cf_ctrl; /* the value to sent to the CF_CONTROLS register */ |
| unsigned char bytes[MAX_I2C_LENGTH]; |
| int burst_size; /* number of words per burst size */ |
| int bytes_per_word=3; |
| int num_bytes; |
| int* p; |
| int error; |
| /* first set DMEM and AIF, leaving other bits intact */ |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_CF_CONTROLS, &cf_ctrl); |
| if (error != Tfa9887_Error_Ok) { |
| return error; |
| } |
| cf_ctrl &= ~0x000E; /* clear AIF & DMEM */ |
| cf_ctrl |= (Tfa9887_DMEM_XMEM<<1); /* set DMEM, leave AIF cleared for autoincrement */ |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_CONTROLS, cf_ctrl); |
| if (error != Tfa9887_Error_Ok) { |
| return error; |
| } |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_MAD, start_offset); |
| if (error != Tfa9887_Error_Ok) { |
| return error; |
| } |
| num_bytes = num_words*bytes_per_word; |
| p=pValues; |
| for (; num_bytes > 0; ) { |
| burst_size = ROUND_DOWN(MAX_I2C_LENGTH, bytes_per_word); |
| if (num_bytes < burst_size) { |
| burst_size = num_bytes; |
| } |
| |
| error = regmap_raw_read(tfa9887_byte->regmap, TFA9887_CF_MEM, bytes,burst_size); |
| if (error != Tfa9887_Error_Ok) { |
| return error; |
| } |
| convertBytes2Data(burst_size, bytes, p); |
| num_bytes -= burst_size; |
| p += burst_size/bytes_per_word; |
| } |
| return Tfa9887_Error_Ok; |
| } |
| |
| int DspSetParam(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte, unsigned char module_id, unsigned char param_id, int num_bytes, const unsigned char *data) |
| { |
| |
| int error; |
| unsigned int cf_ctrl = 0x0002; /* the value to be sent to the CF_CONTROLS register: cf_req=00000000, cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */ |
| unsigned int cf_mad = 0x0001; /* memory address to be accessed (0 : Status, 1 : ID, 2 : parameters) */ |
| unsigned int cf_status; /* the contents of the CF_STATUS register */ |
| unsigned char mem[3]; |
| int rpcStatus = STATUS_OK; |
| int tries = 0; |
| |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_CONTROLS, cf_ctrl); |
| if (error == Tfa9887_Error_Ok) { |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_MAD, cf_mad); |
| } |
| if (error == Tfa9887_Error_Ok) { |
| unsigned char id[3]; |
| id[0] = 0; |
| id[1] = module_id+128; |
| id[2] = param_id; |
| error = regmap_raw_write(tfa9887_byte->regmap, TFA9887_CF_MEM,&id, 3); |
| } |
| |
| error = regmap_raw_write(tfa9887_byte->regmap, TFA9887_CF_MEM, data, num_bytes); |
| |
| if (error == Tfa9887_Error_Ok) { |
| cf_ctrl |= (1<<8) | (1<<4); /* set the cf_req1 and cf_int bit */ |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_CONTROLS, cf_ctrl); |
| |
| do { |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_CF_STATUS, &cf_status); |
| tries++; |
| usleep_range(100, 200); |
| } while ((error == Tfa9887_Error_Ok) && ((cf_status & 0x0100) == 0) && (tries < 100)); /* don't wait forever, DSP is pretty quick to respond (< 1ms) */ |
| |
| if (tries >= 100 && !powerDown) { |
| /* something wrong with communication with DSP */ |
| pr_info("Setparam failed\n"); |
| error = -1; |
| } |
| } |
| cf_ctrl = 0x0002; |
| cf_mad = 0x0000; |
| if (error == Tfa9887_Error_Ok) { |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_CONTROLS,cf_ctrl); |
| } |
| |
| if (error == Tfa9887_Error_Ok) { |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_MAD, cf_mad); |
| } |
| if (error == Tfa9887_Error_Ok) { |
| error = regmap_raw_read(tfa9887_byte->regmap, TFA9887_CF_MEM,&mem,3); |
| rpcStatus = (int)((mem[0] << 16) | (mem[1] << 8) | mem[2]); |
| } |
| if (error == Tfa9887_Error_Ok) { |
| if (rpcStatus != STATUS_OK) { |
| error = rpcStatus+100; |
| //pr_info("RPC rpcStatus =%d\n",error); |
| } |
| } |
| return error; |
| } |
| |
| int DspGetParam(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte, |
| unsigned char module_id, unsigned char param_id, int num_bytes, unsigned char *data) |
| { |
| int error; |
| unsigned int cf_ctrl = 0x0002; /* the value to be sent to the CF_CONTROLS register: cf_req=00000000, cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */ |
| unsigned int cf_mad = 0x0001; /* memory address to be accessed (0 : Status, 1 : ID, 2 : parameters) */ |
| unsigned int cf_status; /* the contents of the CF_STATUS register */ |
| unsigned char mem[3]; |
| unsigned char id[3]; |
| int tries = 0; |
| /* 1) write the id and data to the DSP XMEM */ |
| error = |
| Tfa9887_WriteRegister(tfa9887, TFA9887_CF_CONTROLS, |
| cf_ctrl); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_MAD, cf_mad); |
| id[0] = 0; |
| id[1] = module_id + 128; |
| id[2] = param_id; |
| /* only try MEM once, if error, need to resend mad as well */ |
| error = regmap_raw_write(tfa9887_byte->regmap, TFA9887_CF_MEM, id, 3); |
| /* 2) wake up the DSP and let it process the data */ |
| if (error == 0) { |
| cf_ctrl |= (1 << 8) | (1 << 4); /* set the cf_req1 and cf_int bit */ |
| error = |
| Tfa9887_WriteRegister(tfa9887, TFA9887_CF_CONTROLS, |
| cf_ctrl); |
| } |
| /* 3) wait for the ack */ |
| if (error == Tfa9887_Error_Ok) { |
| do { |
| error = |
| Tfa9887_ReadRegister(tfa9887, TFA9887_CF_STATUS, |
| &cf_status); |
| msleep(1); |
| tries++; |
| } while (( error == 0) && ((cf_status & 0x0100) == 0) |
| && (tries < 100)); /* don't wait forever, DSP is pretty quick to respond (< 1ms) */ |
| if (tries >= 100) { |
| /* something wrong with communication with DSP */ |
| pr_info("GetParam failed\n"); |
| return -1; |
| } |
| } |
| /* 4) check the RPC return value */ |
| cf_ctrl = 0x0002; |
| cf_mad = 0x0000; |
| if (error == Tfa9887_Error_Ok) { |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_CONTROLS,cf_ctrl); |
| } |
| if (error == Tfa9887_Error_Ok) { |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_MAD, cf_mad); |
| } |
| if (error == Tfa9887_Error_Ok) { |
| regmap_raw_read(tfa9887_byte->regmap, TFA9887_CF_MEM,&mem,3); |
| error = (mem[0] << 16) | (mem[1] << 8) | mem[2]; |
| |
| } |
| if (error != Tfa9887_Error_Ok) { |
| pr_info("RPC error\n"); |
| |
| } |
| |
| /* 5) read the resulting data */ |
| if (error == 0) { |
| cf_mad = 0x0002; /* memory address to be accessed (0 : Status, 1 : ID, 2 : parameters) */ |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_CF_MAD, cf_mad); |
| } |
| if (error == 0) { |
| error = |
| regmap_raw_read(tfa9887_byte->regmap, TFA9887_CF_MEM, data, num_bytes); |
| } |
| return error; |
| } |
| |
| int Tfa9887_WriteRegister(struct tfa9887_priv *tfa9887, unsigned int subaddress, unsigned int value) |
| { |
| int error = regmap_write(tfa9887->regmap,subaddress,value); |
| return error; |
| } |
| |
| int Tfa9887_ReadRegister(struct tfa9887_priv *tfa9887, unsigned int subaddress, unsigned int* pValue) |
| { |
| int error = regmap_read(tfa9887->regmap,subaddress,pValue); |
| return error; |
| } |
| |
| void calibrate (struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte, char *calibdata) |
| { |
| |
| int error; |
| int calibrateDone; |
| unsigned int status, value; |
| unsigned char bytes[3]; |
| int data[2]; |
| int tries = 0; |
| |
| if (!recalibration) { |
| SetMute(tfa9887, Tfa9887_Mute_Digital); |
| pr_info("Inside calib\n"); |
| while ((calibrateDone == 0) && (tries < 100)) { |
| error = DspReadMem(tfa9887, tfa9887_byte, 231, 1, &calibrateDone); |
| msleep(10); |
| tries++; |
| } |
| |
| if (calibrateDone) |
| { |
| DspGetParam(tfa9887, tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_GET_RE0, 3, bytes); |
| convertBytes2Data(3, bytes, &data[0]); |
| } |
| speaker_data[420] = 0; |
| speaker_data[421] = 0; |
| speaker_data[422] = 0; |
| error = loadSettings(tfa9887, tfa9887_byte); |
| } |
| calibrateDone = 0; |
| tries = 0; |
| /*SetConfigured*/ |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_SYSTEM_CONTROL, &value); |
| |
| if (error == Tfa9887_Error_Ok) { |
| |
| value |= TFA9887_SYSCTRL_CONFIGURED; |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_SYSTEM_CONTROL, value); |
| } |
| calibrateDone = 0; |
| tries = 0; |
| |
| |
| error = DspReadMem(tfa9887, tfa9887_byte, 231, 1, &calibrateDone); |
| while ((calibrateDone == 0) && (tries < 100)) { |
| error = DspReadMem(tfa9887, tfa9887_byte, 231, 1, &calibrateDone); |
| msleep(10); |
| tries++; |
| } |
| if(tries >= 100) |
| pr_info("Calibrate failed1\n"); |
| |
| calibrateDone = 0; |
| tries = 0; |
| |
| do { |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &status); |
| msleep(10); |
| tries++; |
| } while ( ((status & TFA9887_STATUS_MTPB) == TFA9887_STATUS_MTPB) && (tries < 100)); |
| if (tries >= 100) |
| pr_info("Calibrate failed2\n"); |
| |
| calibrateDone = 0; |
| tries = 0; |
| while ((calibrateDone == 0) && (tries < 100)) { |
| error = DspReadMem(tfa9887, tfa9887_byte, 231, 1, &calibrateDone); |
| msleep(10); |
| tries++; |
| } |
| if (tries >= 100) |
| pr_info("Calibrate failed3\n"); |
| |
| DspGetParam(tfa9887, tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_GET_RE0, 3, bytes); |
| convertBytes2Data(3, bytes, &data[0]); |
| DspReadMem(tfa9887, tfa9887_byte, 232, 1, &data[1]); |
| pr_info("%d %d\n",data[0], data[1]); |
| memcpy(calibdata, (char *)data, 8); |
| } |
| |
| void resetMtpEx(struct tfa9887_priv *tfa9887) |
| { |
| int err; |
| unsigned int mtp, status; |
| int tries = 0; |
| err = Tfa9887_ReadRegister(tfa9887, TFA9887_MTP, &mtp); |
| |
| pr_info("%d****************mtp",mtp); |
| /* all settings loaded, signal the DSP to start calibration, only needed once after cold boot */ |
| /* reset MTPEX bit if needed */ |
| err = Tfa9887_WriteRegister(tfa9887, 0x0B, 0x5A); /* unlock key2 */ |
| err = Tfa9887_WriteRegister(tfa9887, TFA9887_MTP, 1); /* MTPOTC=1, MTPEX=0 */ |
| |
| err = Tfa9887_WriteRegister(tfa9887, 0x62, 1<<11); /* CIMTP=1 */ |
| |
| do { |
| err = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &status); |
| msleep(10); |
| tries++; |
| } while ( ((status & TFA9887_STATUS_MTPB) == TFA9887_STATUS_MTPB) && (tries < 100)); |
| |
| } |
| |
| int checkMTPEX(struct tfa9887_priv *tfa9887) |
| { |
| unsigned int mtp; |
| int err; |
| |
| err = Tfa9887_ReadRegister(tfa9887, TFA9887_MTP, &mtp); |
| if ( mtp & (1<<1)) /* check MTP bit1 (MTPEX) */ |
| return 1; /* MTPEX is 1, calibration is done */ |
| else |
| return 0; /* MTPEX is 0, calibration is not done yet */ |
| } |
| |
| int Tfa9887_Init(int sRate) |
| { |
| int error = 0; |
| srate = sRate; |
| if (tfa9887R) { |
| mutex_lock(&tfa9887R->lock); |
| if (tfa9887R->deviceInit) { |
| coldStartup(tfa9887R, tfa9887R_byte, srate); |
| //Tfa9887_WriteRegister(tfa9887R, 0x0B, 0x5A); /* unlock key2 */ |
| //Tfa9887_WriteRegister(tfa9887R, TFA9887_MTP, 0); /* MTPOTC=1, MTPEX=0 */ |
| setOtc(tfa9887R,1); |
| |
| if((checkMTPEX(tfa9887R) == 0)) { |
| calibration = 1; |
| calibrate(tfa9887R, tfa9887R_byte, &calibdata[0]); |
| } |
| else { |
| error = Init(tfa9887R,tfa9887R_byte, sRate); |
| |
| } |
| } |
| mutex_unlock(&tfa9887R->lock); |
| } |
| |
| if (tfa9887L) { |
| mutex_lock(&tfa9887L->lock); |
| if (tfa9887L->deviceInit) { |
| coldStartup(tfa9887L, tfa9887L_byte, srate); |
| //Tfa9887_WriteRegister(tfa9887L, 0x0B, 0x5A); /* unlock key2 */ |
| //Tfa9887_WriteRegister(tfa9887L, TFA9887_MTP, 0); /* MTPOTC=1, MTPEX=0 */ |
| setOtc(tfa9887L,1); |
| |
| if((checkMTPEX(tfa9887L) == 0)) { |
| calibration = 1; |
| calibrate(tfa9887L, tfa9887L_byte, &calibdata[8]); |
| } |
| else { |
| error = Init(tfa9887L,tfa9887L_byte, sRate); |
| |
| } |
| } |
| mutex_unlock(&tfa9887L->lock); |
| } |
| if (error != 0) |
| pr_info("Failed to Init tfa\n"); |
| return error; |
| } |
| |
| void setOtc(struct tfa9887_priv *tfa9887, unsigned short otcOn) |
| { |
| |
| int err; |
| unsigned int mtp; |
| unsigned int status; |
| int mtpChanged = 0; |
| int tries = 0; |
| |
| err = Tfa9887_ReadRegister(tfa9887, TFA9887_MTP, &mtp); |
| /* set reset MTPEX bit if needed */ |
| if ( (mtp & TFA9887_MTP_MTPOTC) != otcOn) { |
| /* need to change the OTC bit, set MTPEX=0 in any case */ |
| err = Tfa9887_WriteRegister(tfa9887, 0x0B, 0x5A); /* unlock key2 */ |
| |
| err = Tfa9887_WriteRegister(tfa9887, TFA9887_MTP, otcOn); /* MTPOTC=otcOn, MTPEX=0 */ |
| |
| err = Tfa9887_WriteRegister(tfa9887, 0x62, 1<<11); /* CIMTP=1 */ |
| |
| mtpChanged =1; |
| |
| } |
| //Sleep(13*16); /* need to wait until all parameters are copied into MTP */ |
| do { |
| err = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &status); |
| msleep(10); |
| tries++; |
| } while ( ((status & TFA9887_STATUS_MTPB) == TFA9887_STATUS_MTPB) && (tries < 100)); |
| |
| if (mtpChanged) { |
| /* ensure the DSP restarts after this to read out the new value */ |
| err = Tfa9887_WriteRegister(tfa9887, 0x70, 0x1); /* DSP reset */ |
| } |
| |
| } |
| |
| int Tfa9887_SetEq(void) |
| { |
| int error = 0; |
| |
| if (tfa9887R) { |
| mutex_lock(&tfa9887R->lock); |
| if (tfa9887R->deviceInit) |
| error = SetEq(tfa9887R, tfa9887R_byte); |
| mutex_unlock(&tfa9887R->lock); |
| } |
| |
| if (tfa9887L) { |
| mutex_lock(&tfa9887L->lock); |
| if (tfa9887L->deviceInit) |
| error = SetEq(tfa9887L, tfa9887L_byte); |
| mutex_unlock(&tfa9887L->lock); |
| } |
| return error; |
| } |
| |
| int Tfa9887_SetPreset(unsigned int preset) |
| { |
| int error = 0; |
| if (preset != preset_mode) { |
| preset_mode = preset; |
| |
| if (tfa9887R) { |
| mutex_lock(&tfa9887R->lock); |
| if (tfa9887R->deviceInit) |
| error = SetPreset(tfa9887R, tfa9887R_byte); |
| mutex_unlock(&tfa9887R->lock); |
| } |
| |
| if (tfa9887L) { |
| mutex_lock(&tfa9887L->lock); |
| if (tfa9887L->deviceInit) |
| error = SetPreset(tfa9887L, tfa9887L_byte); |
| mutex_unlock(&tfa9887L->lock); |
| } |
| } |
| return error; |
| } |
| |
| int coldStartup(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte, int sRate) |
| { |
| int error,volume_value; |
| unsigned int value; |
| int tries = 0; |
| error = Tfa9887_WriteRegister(tfa9887, 0x09, 0x0002); |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_ReadRegister(tfa9887, 0x09, &value); |
| } |
| if (Tfa9887_Error_Ok == error) { |
| /* DSP must be in control of the amplifier to avoid plops */ |
| value |= TFA9887_SYSCTRL_SEL_ENBL_AMP; |
| error = Tfa9887_WriteRegister(tfa9887, 0x09, value); |
| } |
| |
| /* some other registers must be set for optimal amplifier behaviour */ |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, 0x40, 0x5A6B); |
| } |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, 0x05, 0x13AB); |
| } |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, 0x06, 0x001F); |
| } |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, |
| TFA9887_SPKR_CALIBRATION, 0x3C4E); /* adjusted to mandatory defaults */ |
| } |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, 0x09, 0x025D); |
| } |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, 0x0A, 0x3EC3); |
| } |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, 0x41, 0x0308); |
| } |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, 0x48, 0x0180); |
| } |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, 0x49, 0x0E82); |
| } |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, 0x52, 0x0000); |
| } |
| if (Tfa9887_Error_Ok == error) { |
| error = Tfa9887_WriteRegister(tfa9887, 0x40, 0x0000); |
| } |
| //Set Sampling Frequency |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_I2S_CONTROL, &value); |
| if (error == Tfa9887_Error_Ok) { |
| // clear the 4 bits first |
| value &= (~(0xF<<TFA9887_I2SCTRL_RATE_SHIFT)); |
| switch (sRate) { |
| case 48000: |
| value |= TFA9887_I2SCTRL_RATE_48000; |
| break; |
| case 44100: |
| value |= TFA9887_I2SCTRL_RATE_44100; |
| break; |
| case 32000: |
| value |= TFA9887_I2SCTRL_RATE_32000; |
| break; |
| case 24000: |
| value |= TFA9887_I2SCTRL_RATE_24000; |
| break; |
| case 22050: |
| value |= TFA9887_I2SCTRL_RATE_22050; |
| break; |
| case 16000: |
| value |= TFA9887_I2SCTRL_RATE_16000; |
| break; |
| case 12000: |
| value |= TFA9887_I2SCTRL_RATE_12000; |
| break; |
| case 11025: |
| value |= TFA9887_I2SCTRL_RATE_11025; |
| break; |
| case 8000: |
| value |= TFA9887_I2SCTRL_RATE_08000; |
| break; |
| default: |
| pr_info("unsupported samplerate\n"); |
| error = -1; |
| return error; |
| } |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_I2S_CONTROL, value); |
| } |
| volume_value = volume_step[PRESET_DEFAULT]; |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_AUDIO_CONTROL, &value); |
| if(error == Tfa9887_Error_Ok) { |
| value = (value&0x00FF) | (unsigned int)(volume_value<<8); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_AUDIO_CONTROL, value); |
| } |
| //PowerUp |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_SYSTEM_CONTROL, &value); |
| if(error == Tfa9887_Error_Ok) { |
| value &= ~(TFA9887_SYSCTRL_POWERDOWN); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_SYSTEM_CONTROL, value); |
| } |
| |
| //Waiting for IC to startup |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &value); |
| do { |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &value); |
| msleep(1); |
| tries++; |
| } while ((error == Tfa9887_Error_Ok) && ((value & TFA9887_STATUS_PLLS) == 0) && (tries < 100)); |
| |
| //Firmware |
| error = ProcessPatchFile(tfa9887, tfa9887_byte, 10, coldpatch_data); |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_STATUS, &value); |
| if(value & TFA9887_STATUS_ACS) |
| //pr_info("TFA COLD BOOTED\n"); |
| error = ProcessPatchFile(tfa9887, tfa9887_byte, sizeof(n1d2_data), n1d2_data); |
| |
| return error; |
| } |
| |
| int Init(struct tfa9887_priv *tfa9887,struct tfa9887_priv *tfa9887_byte, int sRate) |
| { |
| int error; |
| unsigned int value; |
| |
| error = loadSettings(tfa9887, tfa9887_byte); |
| if(error != Tfa9887_Error_Ok) { |
| pr_info("Loading Settings Failed\n"); |
| } |
| |
| error = stereoRouting(tfa9887); |
| |
| if(error != Tfa9887_Error_Ok) { |
| pr_info("Stereo routing Failed\n"); |
| } |
| |
| //SetConfigured |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_SYSTEM_CONTROL, &value); |
| if(error == Tfa9887_Error_Ok) |
| { |
| value |= TFA9887_SYSCTRL_CONFIGURED; |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_SYSTEM_CONTROL, value); |
| } |
| if (!calibration) { |
| SetMute(tfa9887, Tfa9887_Mute_Amplifier); |
| //PowerDown |
| if(error == Tfa9887_Error_Ok) |
| { |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_SYSTEM_CONTROL, &value); |
| value |= TFA9887_SYSCTRL_POWERDOWN; |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_SYSTEM_CONTROL, value); |
| } |
| } |
| |
| return error; |
| } |
| |
| int SetEq(struct tfa9887_priv *tfa9887,struct tfa9887_priv *tfa9887_byte) |
| { |
| int error = 0; |
| if (eq_mode == IN_HAND_MODE) { |
| //pr_info("Setting hand mode\n"); |
| error = DspSetParam(tfa9887,tfa9887_byte, MODULE_BIQUADFILTERBANK,0, 180, eq_data_hand); |
| } else if (eq_mode == ON_DESK_MODE) { |
| //pr_info("setting deskmode\n"); |
| error = DspSetParam(tfa9887,tfa9887_byte, MODULE_BIQUADFILTERBANK,0, 180, eq_data_table); |
| } |
| return error; |
| } |
| |
| int SetPreset(struct tfa9887_priv *tfa9887,struct tfa9887_priv *tfa9887_byte) |
| { |
| int error = 0; |
| unsigned int value = 0; |
| unsigned int volume_value = 0; |
| |
| switch(preset_mode) { |
| case 0: |
| error = DspSetParam(tfa9887,tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_SET_PRESET, 87, preset_data0); |
| break; |
| case 1: |
| error = DspSetParam(tfa9887,tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_SET_PRESET, 87, preset_data1); |
| break; |
| case 2: |
| error = DspSetParam(tfa9887,tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_SET_PRESET, 87, preset_data2); |
| break; |
| case 3: |
| error = DspSetParam(tfa9887,tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_SET_PRESET, 87, preset_data3); |
| break; |
| case 4: |
| error = DspSetParam(tfa9887,tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_SET_PRESET, 87, preset_data4); |
| break; |
| default: |
| return -1; |
| } |
| volume_value = volume_step[preset_mode]; |
| //volume_value = volume_step[PRESET_DEFAULT]; |
| //pr_info("%u %u\n",preset_mode,volume_value); |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_AUDIO_CONTROL, &value); |
| if(error == Tfa9887_Error_Ok) { |
| value = (value&0x00FF) | (unsigned int)(volume_value<<8); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_AUDIO_CONTROL, value); |
| } |
| return error; |
| } |
| |
| int loadSettings(struct tfa9887_priv *tfa9887,struct tfa9887_priv *tfa9887_byte) |
| { |
| int error; |
| //Load settings |
| error = DspSetParam(tfa9887,tfa9887_byte,MODULE_SPEAKERBOOST, PARAM_SET_LSMODEL, 423, speaker_data); |
| error = DspSetParam(tfa9887,tfa9887_byte, MODULE_SPEAKERBOOST, PARAM_SET_CONFIG, 165, config_data); |
| SetPreset(tfa9887,tfa9887_byte); |
| SetEq(tfa9887,tfa9887_byte); |
| return error; |
| } |
| |
| int stereoRouting(struct tfa9887_priv *tfa9887) |
| { |
| int error; |
| unsigned int value; |
| if(tfa9887 == tfa9887L) { |
| //select channel |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_I2S_CONTROL, &value); |
| // clear the 2 bits first |
| value &= ~(0x3<<TFA9887_I2SCTRL_CHANSEL_SHIFT); |
| |
| value |=(1<<TFA9887_I2SCTRL_CHANSEL_SHIFT); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_I2S_CONTROL, value); |
| |
| //select ouput left for gain |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_I2S_SEL, &value); |
| value &= ~(0x7<<TFA9887_I2SSEL_I2SOUT_LEFT_SHIFT); |
| value |=(1<<TFA9887_I2SSEL_I2SOUT_LEFT_SHIFT); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_I2S_SEL, value); |
| //Select stereo gain |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_I2S_CONTROL, &value); |
| value &= ~(0x1<<TFA9887_I2SCTRL_DATAI2_SHIFT); |
| value |=(1<<TFA9887_I2SCTRL_DATAI2_SHIFT); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_I2S_CONTROL, value); |
| |
| //select output right for current sense |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_I2S_SEL, &value); |
| value &= ~(0x7<<TFA9887_I2SSEL_I2SOUT_RIGHT_SHIFT); |
| value |=(0<<TFA9887_I2SSEL_I2SOUT_RIGHT_SHIFT); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_I2S_SEL, value); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_I2S_SEL, value); |
| //pr_info("Tfa inside left\n"); |
| |
| } |
| else if (tfa9887 == tfa9887R) { |
| // clear the 2 bits first |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_I2S_CONTROL, &value); |
| value &= ~(0x3<<TFA9887_I2SCTRL_CHANSEL_SHIFT); |
| |
| value |=(2<<TFA9887_I2SCTRL_CHANSEL_SHIFT); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_I2S_CONTROL, value); |
| |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_I2S_SEL, &value); |
| value &= ~(0x7<<TFA9887_I2SSEL_I2SOUT_RIGHT_SHIFT); |
| value |=(1<<TFA9887_I2SSEL_I2SOUT_RIGHT_SHIFT); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_I2S_SEL, value); |
| |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_I2S_CONTROL, &value); |
| value &= ~(0x1<<TFA9887_I2SCTRL_DATAI2_SHIFT); |
| value |=(0<<TFA9887_I2SCTRL_DATAI2_SHIFT); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_I2S_CONTROL, value); |
| |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_I2S_SEL, &value); |
| value &= ~(0x7<<TFA9887_I2SSEL_I2SOUT_LEFT_SHIFT); |
| value |=(0<<TFA9887_I2SSEL_I2SOUT_LEFT_SHIFT); |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_I2S_SEL, value); |
| //pr_info("tfa inside right\n"); |
| |
| } |
| else |
| { |
| error = -1; |
| } |
| return error; |
| } |
| |
| int Tfa9887_Powerdown(int powerdown) |
| { |
| int error = 0; |
| |
| powerDown = powerdown; |
| |
| if (tfa9887R) { |
| mutex_lock(&tfa9887R->lock); |
| if (tfa9887R->deviceInit) |
| error = Powerdown(tfa9887R, tfa9887R_byte, powerdown); |
| mutex_unlock(&tfa9887R->lock); |
| } |
| |
| if (tfa9887L) { |
| mutex_lock(&tfa9887L->lock); |
| if (tfa9887L->deviceInit) |
| error = Powerdown(tfa9887L, tfa9887L_byte, powerdown); |
| mutex_unlock(&tfa9887L->lock); |
| } |
| return error; |
| } |
| |
| EXPORT_SYMBOL(Tfa9887_Powerdown); |
| |
| int Powerdown(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte, int powerdown) |
| { |
| int error; |
| unsigned int value; |
| |
| /* read the SystemControl register, modify the bit and write again */ |
| error = Tfa9887_ReadRegister(tfa9887, TFA9887_SYSTEM_CONTROL, &value); |
| if (error != Tfa9887_Error_Ok) { |
| return error; |
| } |
| |
| switch(powerdown) { |
| case 1: |
| value |= TFA9887_SYSCTRL_POWERDOWN; |
| SetMute(tfa9887,Tfa9887_Mute_Amplifier); |
| break; |
| case 0: |
| value &= ~(TFA9887_SYSCTRL_POWERDOWN); |
| break; |
| default: |
| return -1; |
| } |
| error = Tfa9887_WriteRegister(tfa9887, TFA9887_SYSTEM_CONTROL, value); |
| if(!powerdown) { |
| SetMute(tfa9887,Tfa9887_Mute_Off); |
| SetPreset(tfa9887,tfa9887_byte); |
| SetEq(tfa9887,tfa9887_byte); |
| } |
| |
| return error; |
| } |
| |
| int SetMute(struct tfa9887_priv *tfa9887, Tfa9887_Mute_t mute) |
| { |
| int error; |
| unsigned int audioctrl_value; |
| unsigned int sysctrl_value; |
| error = |
| Tfa9887_ReadRegister(tfa9887, TFA9887_AUDIO_CONTROL, |
| &audioctrl_value); |
| if (error != Tfa9887_Error_Ok) |
| return error; |
| error = |
| Tfa9887_ReadRegister(tfa9887, TFA9887_SYSTEM_CONTROL, |
| &sysctrl_value); |
| if (error != Tfa9887_Error_Ok) |
| return error; |
| switch (mute) { |
| case Tfa9887_Mute_Off: |
| /* previous state can be digital or amplifier mute, |
| * clear the cf_mute and set the enbl_amplifier bits |
| */ |
| audioctrl_value &= ~(TFA9887_AUDIOCTRL_MUTE); |
| sysctrl_value |= TFA9887_SYSCTRL_ENBL_AMP; |
| break; |
| case Tfa9887_Mute_Digital: |
| /* expect the amplifier to run */ |
| /* set the cf_mute bit */ |
| audioctrl_value |= TFA9887_AUDIOCTRL_MUTE; |
| /* set the enbl_amplifier bit */ |
| sysctrl_value |= TFA9887_SYSCTRL_ENBL_AMP; |
| break; |
| case Tfa9887_Mute_Amplifier: |
| /* clear the cf_mute bit */ |
| audioctrl_value &= ~TFA9887_AUDIOCTRL_MUTE; |
| /* clear the enbl_amplifier bit */ |
| sysctrl_value &= ~TFA9887_SYSCTRL_ENBL_AMP; |
| break; |
| default: |
| error = -1; |
| } |
| if (error != Tfa9887_Error_Ok) |
| return error; |
| error = |
| Tfa9887_WriteRegister(tfa9887, TFA9887_AUDIO_CONTROL, |
| audioctrl_value); |
| if (error != Tfa9887_Error_Ok) |
| return error; |
| error = |
| Tfa9887_WriteRegister(tfa9887, TFA9887_SYSTEM_CONTROL, |
| sysctrl_value); |
| return error; |
| } |
| bool tfa9887_readable_register(struct device *dev, unsigned int reg) |
| { |
| return true; |
| } |
| |
| bool tfa9887_volatile_register(struct device *dev, unsigned int reg) |
| { |
| return true; |
| } |
| |
| static const struct regmap_config tfa9887_regmap = { |
| .reg_bits = 8, |
| .val_bits = 16, |
| .volatile_reg = tfa9887_volatile_register, |
| .readable_reg = tfa9887_readable_register, |
| .cache_type = REGCACHE_NONE, |
| }; |
| |
| static const struct regmap_config tfa9887_regmap_byte = { |
| .reg_bits = 8, |
| .val_bits = 8, |
| .volatile_reg = tfa9887_volatile_register, |
| .readable_reg = tfa9887_readable_register, |
| .cache_type = REGCACHE_NONE, |
| }; |
| static ssize_t tfa9887_cal_show(struct kobject *kobj, |
| struct kobj_attribute *attr, char *buf) |
| { |
| //printk("!tfa9887_cal_show\n"); |
| if (calibration) { |
| memcpy(buf, calibdata, 16); |
| return 16; |
| //pr_info("copying data\n"); |
| } |
| else |
| return -1; |
| } |
| |
| static ssize_t tfa9887_cal_store(struct kobject *kobj, |
| struct kobj_attribute *attr, const char *buf, size_t count) |
| { |
| ssize_t ret = count; |
| //printk("+tfa9887_cal_store: %p, %d\n", buf, count); |
| |
| if (!buf || !count) { |
| ret = -EINVAL; |
| goto fail; |
| } |
| if (count == 6) { |
| if (calibration) { |
| recalibration = 1; |
| tegra_asoc_enable_clocks(); |
| memcpy(&speaker_data[420],buf,3); |
| recalibrate(tfa9887R, tfa9887R_byte); |
| memcpy(&speaker_data[420],buf+3,3); |
| recalibrate(tfa9887L, tfa9887L_byte); |
| recalibration = 0; |
| calibration = 0; |
| tegra_asoc_disable_clocks(); |
| } |
| } |
| fail: |
| //printk("-tfa9887_cal_store: %d\n", count); |
| return ret; |
| } |
| |
| void recalibrate(struct tfa9887_priv *tfa9887, struct tfa9887_priv *tfa9887_byte) { |
| |
| unsigned int value; |
| if (tfa9887) { |
| mutex_lock(&tfa9887->lock); |
| if (tfa9887->deviceInit) { |
| resetMtpEx(tfa9887); |
| SetMute(tfa9887, Tfa9887_Mute_Amplifier); |
| coldStartup(tfa9887, tfa9887_byte, srate); |
| Init(tfa9887,tfa9887_byte, srate); |
| calibrate(tfa9887, tfa9887_byte, &calibdata[0]); |
| Tfa9887_ReadRegister(tfa9887, TFA9887_SYSTEM_CONTROL, &value); |
| value |= TFA9887_SYSCTRL_POWERDOWN; |
| Tfa9887_WriteRegister(tfa9887, TFA9887_SYSTEM_CONTROL, value); |
| } |
| mutex_unlock(&tfa9887->lock); |
| } |
| } |
| |
| static ssize_t tfa9887_config_show(struct kobject *kobj, |
| struct kobj_attribute *attr, char *buf) |
| { |
| //printk("!tfa9887_config_show\n"); |
| |
| if (buf) { |
| if (eq_mode == 1) |
| *buf = '1'; |
| else if (eq_mode == 2) |
| *buf = '2'; |
| else |
| return -EINVAL; |
| } |
| printk("%c\n",*buf); |
| return 1; |
| } |
| |
| static ssize_t tfa9887_config_store(struct kobject *kobj, |
| struct kobj_attribute *attr, const char *buf, size_t count) |
| { |
| ssize_t ret = count; |
| |
| //printk("+tfa9887_config_store: %p, %d\n", buf, count); |
| |
| if (!buf || !count) { |
| ret = -EINVAL; |
| goto fail; |
| } |
| if (*buf == '2') { |
| pr_info("IN HAND MODE\n"); |
| eq_mode = 2; |
| } |
| else if (*buf == '1'){ |
| pr_info("IN DESK MODE\n"); |
| eq_mode = 1; |
| } |
| Tfa9887_SetEq(); |
| fail: |
| //printk("-tfa9887_config_store: %d\n", count); |
| return ret; |
| } |
| |
| static ssize_t tfa9887_vol_show(struct kobject *kobj, |
| struct kobj_attribute *attr, char *buf) |
| { |
| printk("!tfa9887_vol_show\n"); |
| return 0; |
| } |
| |
| static ssize_t tfa9887_vol_store(struct kobject *kobj, |
| struct kobj_attribute *attr, const char *buf, size_t count) |
| { |
| ssize_t ret = count; |
| unsigned int preset; |
| |
| //printk("+tfa9887_vol_store: %d, %d\n", *buf, count); |
| |
| if (!buf || !count) { |
| ret = -EINVAL; |
| goto fail; |
| } |
| if (*buf >= DB_CUTOFF_INDEX) |
| preset = MAX_DB_INDEX - *buf; |
| else |
| preset = PRESET_DEFAULT; |
| |
| Tfa9887_SetPreset(preset); |
| fail: |
| //printk("-tfa9887_vol_store: %d\n", count); |
| return ret; |
| } |
| |
| static int tfa9887R_i2c_probe(struct i2c_client *i2c, |
| const struct i2c_device_id *id) |
| { |
| unsigned int val; |
| int ret; |
| |
| pr_info("tfa9887R_i2c_probe\n"); |
| tfa9887R = devm_kzalloc(&i2c->dev, sizeof(struct tfa9887_priv), |
| GFP_KERNEL); |
| tfa9887R_byte = devm_kzalloc(&i2c->dev, sizeof(struct tfa9887_priv), |
| GFP_KERNEL); |
| |
| if (tfa9887R == NULL) |
| return -ENOMEM; |
| tfa9887R->regmap = regmap_init_i2c(i2c, &tfa9887_regmap); |
| tfa9887R_byte->regmap = regmap_init_i2c(i2c, &tfa9887_regmap_byte); |
| if (IS_ERR(tfa9887R->regmap)) { |
| ret = PTR_ERR(tfa9887R->regmap); |
| dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
| ret); |
| return ret; |
| } |
| |
| i2c_set_clientdata(i2c, tfa9887R); |
| i2c_set_clientdata(i2c, tfa9887R_byte); |
| mutex_init(&tfa9887R->lock); |
| tfa9887R->irq = i2c->irq; |
| tfa9887R_byte->irq = i2c->irq; |
| ret = regmap_read(tfa9887R->regmap, TFA9887_REVISIONNUMBER, &val); |
| if (ret != 0) { |
| dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret); |
| goto err; |
| } |
| dev_info(&i2c->dev, "TFA9887 revision %d\n",val); |
| tfa9887_kobj = kobject_create_and_add("tfa9887", kernel_kobj); |
| |
| ret = sysfs_create_file(tfa9887_kobj, &tfa9887_config.attr); |
| printk("tfa9887_add_sysfs ret=%d\n", ret); |
| if (ret != 0) { |
| dev_err(&i2c->dev, "Failed to add sysfs: %d\n", ret); |
| goto err; |
| } |
| ret = sysfs_create_file(tfa9887_kobj, &tfa9887_cal.attr); |
| printk("tfa9887_add_sysfs ret=%d\n", ret); |
| if (ret != 0) { |
| dev_err(&i2c->dev, "Failed to add sysfs: %d\n", ret); |
| goto err; |
| } |
| ret = sysfs_create_file(tfa9887_kobj, &tfa9887_vol.attr); |
| printk("tfa9887_add_sysfs ret=%d\n", ret); |
| if (ret != 0) { |
| dev_err(&i2c->dev, "Failed to add sysfs: %d\n", ret); |
| goto err; |
| } |
| if (tfa9887R) { |
| mutex_lock(&tfa9887R->lock); |
| tfa9887R->deviceInit = true; |
| mutex_unlock(&tfa9887R->lock); |
| } |
| eq_mode = IN_HAND_MODE; |
| preset_mode = PRESET_DEFAULT; |
| return 0; |
| err: |
| regmap_exit(tfa9887R->regmap); |
| return ret; |
| } |
| |
| static int tfa9887R_i2c_remove(struct i2c_client *client) |
| { |
| struct tfa9887_priv *tfa9887R = i2c_get_clientdata(client); |
| regmap_exit(tfa9887R->regmap); |
| sysfs_remove_file(tfa9887_kobj, &tfa9887_config.attr); |
| sysfs_remove_file(tfa9887_kobj, &tfa9887_cal.attr); |
| sysfs_remove_file(tfa9887_kobj, &tfa9887_vol.attr); |
| kobject_del(tfa9887_kobj); |
| return 0; |
| } |
| |
| static void tfa9887R_i2c_shutdown(struct i2c_client *i2c) |
| { |
| if (tfa9887R) { |
| mutex_lock(&tfa9887R->lock); |
| if (i2c->irq) |
| disable_irq(i2c->irq); |
| tfa9887R->deviceInit = false; |
| mutex_unlock(&tfa9887R->lock); |
| } |
| } |
| |
| static const struct of_device_id tfa9887R_of_match[] = { |
| { .compatible = "nxp,tfa9887R", }, |
| {}, |
| }; |
| MODULE_DEVICE_TABLE(of, tfa9887R_of_match); |
| |
| static const struct i2c_device_id tfa9887R_i2c_id[] = { |
| { "tfa9887R", 0 }, |
| { } |
| }; |
| MODULE_DEVICE_TABLE(i2c, tfa9887R_i2c_id); |
| |
| static struct i2c_driver tfa9887R_i2c_driver = { |
| .driver = { |
| .name = "tfa9887R", |
| .owner = THIS_MODULE, |
| .of_match_table = tfa9887R_of_match, |
| }, |
| .probe = tfa9887R_i2c_probe, |
| .remove = tfa9887R_i2c_remove, |
| .id_table = tfa9887R_i2c_id, |
| .shutdown = tfa9887R_i2c_shutdown, |
| }; |
| |
| static int tfa9887L_i2c_probe(struct i2c_client *i2c, |
| const struct i2c_device_id *id) |
| { |
| unsigned int val; |
| int ret; |
| |
| pr_info("tfa9887L_i2c_probe\n"); |
| tfa9887L = devm_kzalloc(&i2c->dev, sizeof(struct tfa9887_priv), |
| GFP_KERNEL); |
| tfa9887L_byte = devm_kzalloc(&i2c->dev, sizeof(struct tfa9887_priv), |
| GFP_KERNEL); |
| |
| if (tfa9887L == NULL) |
| return -ENOMEM; |
| tfa9887L->regmap = regmap_init_i2c(i2c, &tfa9887_regmap); |
| tfa9887L_byte->regmap = regmap_init_i2c(i2c, &tfa9887_regmap_byte); |
| if (IS_ERR(tfa9887L->regmap)) { |
| ret = PTR_ERR(tfa9887L->regmap); |
| dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
| ret); |
| return ret; |
| } |
| |
| i2c_set_clientdata(i2c, tfa9887L); |
| mutex_init(&tfa9887L->lock); |
| tfa9887L->irq = i2c->irq; |
| ret = regmap_read(tfa9887L->regmap, TFA9887_REVISIONNUMBER, &val); |
| if (ret != 0) { |
| dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret); |
| goto err; |
| } |
| dev_info(&i2c->dev, "TFA9887 revision %d\n",val); |
| if (tfa9887L) { |
| mutex_lock(&tfa9887L->lock); |
| tfa9887L->deviceInit = true; |
| mutex_unlock(&tfa9887L->lock); |
| } |
| return 0; |
| err: |
| regmap_exit(tfa9887L->regmap); |
| return ret; |
| } |
| |
| static int tfa9887L_i2c_remove(struct i2c_client *client) |
| { |
| struct tfa9887_priv *tfa9887L = i2c_get_clientdata(client); |
| regmap_exit(tfa9887L->regmap); |
| return 0; |
| } |
| |
| static void tfa9887L_i2c_shutdown(struct i2c_client *i2c) |
| { |
| if (tfa9887L) { |
| mutex_lock(&tfa9887L->lock); |
| if (i2c->irq) |
| disable_irq(i2c->irq); |
| tfa9887L->deviceInit = false; |
| mutex_unlock(&tfa9887L->lock); |
| } |
| } |
| |
| static const struct of_device_id tfa9887L_of_match[] = { |
| { .compatible = "nxp,tfa9887L", }, |
| {}, |
| }; |
| MODULE_DEVICE_TABLE(of, tfa9887L_of_match); |
| |
| static const struct i2c_device_id tfa9887L_i2c_id[] = { |
| { "tfa9887L", 0 }, |
| { } |
| }; |
| MODULE_DEVICE_TABLE(i2c, tfa9887L_i2c_id); |
| |
| static struct i2c_driver tfa9887L_i2c_driver = { |
| .driver = { |
| .name = "tfa9887L", |
| .owner = THIS_MODULE, |
| .of_match_table = tfa9887L_of_match, |
| }, |
| .probe = tfa9887L_i2c_probe, |
| .remove = tfa9887L_i2c_remove, |
| .id_table = tfa9887L_i2c_id, |
| .shutdown = tfa9887L_i2c_shutdown, |
| }; |
| |
| static int __init tfa9887_modinit(void) |
| { |
| int ret = 0; |
| ret = i2c_add_driver(&tfa9887R_i2c_driver); |
| if (ret != 0) { |
| printk(KERN_ERR "Failed to register tfa9887 I2C driver: %d\n", |
| ret); |
| } |
| ret = i2c_add_driver(&tfa9887L_i2c_driver); |
| if (ret != 0) { |
| printk(KERN_ERR "Failed to register tfa9887 I2C driver: %d\n", |
| ret); |
| } |
| return ret; |
| } |
| module_init(tfa9887_modinit); |
| |
| static void __exit tfa9887_exit(void) |
| { |
| i2c_del_driver(&tfa9887R_i2c_driver); |
| i2c_del_driver(&tfa9887L_i2c_driver); |
| } |
| module_exit(tfa9887_exit); |
| |
| MODULE_AUTHOR("Vinod Subbarayalu <vsubbarayalu@nvidia.com>, Scott Peterson <speterson@nvidia.com>"); |
| MODULE_DESCRIPTION("TFA9887 Audio Codec driver"); |
| MODULE_LICENSE("GPL"); |
| |