/* * 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 #include #include #include #include #include #include #include #include #include #include #include #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<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 , Scott Peterson "); MODULE_DESCRIPTION("TFA9887 Audio Codec driver"); MODULE_LICENSE("GPL");