blob: 37170ac69f9d03f98b31ffb76d9b574569932658 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
2* All Rights Reserved
3*
4* MARVELL CONFIDENTIAL
5* Copyright 2012 Marvell International Ltd All Rights Reserved.
6* The source code contained or described herein and all documents related to
7* the source code ("Material") are owned by Marvell International Ltd or its
8* suppliers or licensors. Title to the Material remains with Marvell International Ltd
9* or its suppliers and licensors. The Material contains trade secrets and
10* proprietary and confidential information of Marvell or its suppliers and
11* licensors. The Material is protected by worldwide copyright and trade secret
12* laws and treaty provisions. No part of the Material may be used, copied,
13* reproduced, modified, published, uploaded, posted, transmitted, distributed,
14* or disclosed in any way without Marvell's prior express written permission.
15*
16* No license under any patent, copyright, trade secret or other intellectual
17* property right is granted to or conferred upon you by disclosure or delivery
18* of the Materials, either expressly, by implication, inducement, estoppel or
19* otherwise. Any license under such intellectual property rights must be
20* express and approved by Marvell in writing.
21*
22*/
23
24#define LOG_TAG "acm_ach_ustica"
25#define LOG_NDEBUG 0
26
27#include <cutils/log.h>
28#include "acm_ustica.h"
29
30#ifdef PXA1826_AUDIO
31#ifndef ACM_ALSA_INIT
32#define ACM_ALSA_INIT
33#endif
34#endif
35
36extern int codec_reg_num;
37
38static void Ustica_Enable(void);
39static void Ustica_Disable(void);
40static void Ustica_Reset(void);
41static void Ustica_GetTypeAndID(int *type, unsigned char *id);
42static ACH_ReturnCode Ustica_Handle(void *setting);
43
44ACH_ComponentHandler ustica_handler = {
45 COMPONENT_INACTIVE,
46 0,
47 Ustica_Enable,
48 Ustica_Disable,
49 Ustica_Reset,
50 Ustica_GetTypeAndID,
51 Ustica_Handle,
52};
53
54extern int I2CInit(void);
55extern int I2CDeInit(void);
56extern void I2CWrite(unsigned char numid, unsigned short value);
57extern void I2CRead(unsigned char numid, unsigned char *value);
58
59static void Ustica_RegSet(unsigned char numid, unsigned char value) {
60#ifndef DEBUG_FAKE_ACH
61 I2CWrite(numid, value);
62#else
63 LOGD(Ustica_RegSet, " FAKE_ACH: %s(0x%x, 0x%x)", __FUNCTION__, numid, value);
64#endif
65}
66
67void Ustica_RegGet(unsigned char numid, unsigned char *value) {
68#ifndef DEBUG_FAKE_ACH
69 I2CRead(numid, value);
70#else
71 LOGD(Ustica_RegGet, " FAKE_ACH: %s(0x%x, ..)", __FUNCTION__, numid);
72#endif
73}
74
75static void Ustica_ResetRegCache() {
76 int size = sizeof(reg_cache) / sizeof(reg_cache[0]);
77 int i = 0;
78
79 for (i = 0; i < size; i++) {
80 reg_cache[i].reg_value = reg_cache[i].reg_default;
81 }
82}
83
84unsigned char Ustica_GetRegNumId(unsigned char reg_index) {
85 unsigned char i = 0;
86
87 for (i = 0; i < NUM_OF_REGS; i++) {
88 if (reg_cache[i].reg_index == reg_index) {
89 return codec_reg_num + i;
90 }
91 }
92
93 return 0;
94}
95
96//--------------------------------------------------------------
97//-------- External ACH APIs
98//--------------------------------------------------------------
99#ifdef ACM_ALSA_INIT
100// NOTE about pair Enable/Disable
101// On startup Disable could be called without Enable as Init/Reset sequence
102// Skip DeInit for first Disable without Enable
103//
104static int _acm_initialized;
105#endif
106
107static void Ustica_Enable(void) {
108 LOGI(Ustica_Enable, "%s: enable ustica component", __FUNCTION__);
109#ifdef ACM_ALSA_INIT
110 _acm_initialized = 1;
111 I2CInit(); //adaptor to alsa-mixer
112#endif
113}
114
115static void Ustica_Disable(void) {
116 LOGI(Ustica_Disable, "%s: disable ustica component", __FUNCTION__);
117#ifdef ACM_ALSA_INIT
118 if (_acm_initialized) {
119 _acm_initialized = 1;
120 I2CDeInit(); //adaptor to alsa-mixer
121 }
122#endif
123}
124
125static void Ustica_Reset(void) {
126 LOGI(Ustica_Reset, "%s: Reset ustica registers!", __FUNCTION__);
127 int size = sizeof(reg_cache) / sizeof(reg_cache[0]);
128 int size_col = sizeof(reg_cache[0]) / sizeof(unsigned char);
129 int i, k = 0;
130 unsigned char j, numid, value, cache_idx;
131 Ustica_RegisterCache reg_cache_inorder[size];
132
133#ifdef ACM_ALSA_INIT
134 I2CInit(); //make sure to enable mixer before and close after this operation
135#endif
136 for (j = 0x0; j <= 0xff; j++){
137 if (k == size){
138 LOGI(Ustica_Reset0, "%s: copy completed !", __FUNCTION__);
139 break;
140 }
141
142 for (i = 0; i < size; i++) {
143 if (reg_cache[i].reg_prior == j) {
144 memcpy(&reg_cache_inorder[k], &reg_cache[i], size_col);
145 k++;
146 }
147 }
148 }
149
150 for (k = 0; k < size; k++) {
151 if (reg_cache_inorder[k].reg_prior == 0x0) {
152 continue;
153 } else {
154 break;
155 }
156 }
157
158 for (; k < size; k++) {
159 numid = Ustica_GetRegNumId(reg_cache_inorder[k].reg_index);
160 if (numid == 0) {
161 LOGW(Ustica_Reset1, "%s: Invalid numid = %d!", __FUNCTION__, numid);
162 continue;
163 }
164
165 value = reg_cache_inorder[k].reg_default;
166 cache_idx = numid - codec_reg_num;
167 if (cache_idx < size)
168 reg_cache[cache_idx].reg_value = value;
169 Ustica_RegSet(numid, value);
170#ifdef DEBUG_USTICA
171 LOGI(Ustica_Reset2, "%s: resets ustica register 0x%lx to value --> 0x%lx",
172 __FUNCTION__,
173 reg_cache_inorder[k].reg_index,
174 value);
175#endif
176 }
177#ifdef ACM_ALSA_INIT
178 I2CDeInit(); //make sure to enable mixer before and close after this operation
179#endif
180}
181
182static void Ustica_GetTypeAndID(int *type, unsigned char *id){
183 LOGI(Ustica_GetTypeAndID, "%s: Get type and ID for ustica component", __FUNCTION__);
184 *type = COMPONENT_TYPE_POWER;
185#ifdef ACM_ALSA_INIT
186 I2CInit(); //make sure to enable mixer before and close after this operation
187#endif
188 Ustica_RegGet(USTICA_ID_REG, id);
189#ifdef ACM_ALSA_INIT
190 I2CDeInit(); //make sure to enable mixer before and close after this operation
191#endif
192}
193
194static ACH_ReturnCode Ustica_Handle(void *setting) {
195 ACH_ComponentParameter *param = (ACH_ComponentParameter *)setting;
196 unsigned char numid, value, cache_idx;
197
198 if (param && param->i2c.reg_value) {
199 numid = Ustica_GetRegNumId(param->i2c.reg_index);
200 if (numid > 0) {
201 //compare with register cache
202 cache_idx = numid - codec_reg_num;
203 value = (reg_cache[cache_idx].reg_value & ~param->i2c.reg_mask) | (*param->i2c.reg_value);
204 if ((reg_cache[cache_idx].reg_value & param->i2c.reg_mask) != (*param->i2c.reg_value)) {
205#ifdef DEBUG_USTICA
206 LOGI(Ustica_Handle, "%s: set register 0x%lx [0x%lx --> 0x%lx]",
207 __FUNCTION__,
208 param->i2c.reg_index,
209 reg_cache[cache_idx].reg_value,
210 value);
211#endif
212
213 reg_cache[cache_idx].reg_value = value;
214 Ustica_RegSet(numid, reg_cache[cache_idx].reg_value);
215 } else {
216#ifdef DEBUG_USTICA
217 LOGI(Ustica_Handle1, "%s: set register 0x%lx [0x%lx --> 0x%lx] (unchanged)",
218 __FUNCTION__,
219 param->i2c.reg_index,
220 reg_cache[cache_idx].reg_value,
221 reg_cache[cache_idx].reg_value);
222#endif
223 }
224 }
225 }
226
227 return ACH_RC_OK;
228}