aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/tlv320aic326x_mini-dsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/tlv320aic326x_mini-dsp.c')
-rw-r--r--sound/soc/codecs/tlv320aic326x_mini-dsp.c1796
1 files changed, 1796 insertions, 0 deletions
diff --git a/sound/soc/codecs/tlv320aic326x_mini-dsp.c b/sound/soc/codecs/tlv320aic326x_mini-dsp.c
new file mode 100644
index 00000000000..6d55abb4dac
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic326x_mini-dsp.c
@@ -0,0 +1,1796 @@
1/*
2 * linux/sound/soc/codecs/tlv320aic326x_mini-dsp.c
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * This package is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
11 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
12 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13 *
14 * The TLV320AIC3262 is a flexible, low-power, low-voltage stereo audio
15 * codec with digital microphone inputs and programmable outputs.
16 *
17 * History:
18 *
19 * Rev 0.1 Added the miniDSP Support 01-03-2011
20 *
21 * Rev 0.2 Updated the code-base for miniDSP switching and
22 * mux control update. 21-03-2011
23 *
24 * Rev 0.3 Updated the code-base to support Multi-Configuration feature
25 * of PPS GDE
26 */
27
28/*
29 *****************************************************************************
30 * INCLUDES
31 *****************************************************************************
32 */
33#include <linux/module.h>
34#include <linux/moduleparam.h>
35#include <linux/init.h>
36#include <linux/kernel.h>
37#include <linux/fs.h>
38#include <linux/types.h>
39#include <linux/kdev_t.h>
40#include <linux/cdev.h>
41#include <linux/device.h>
42#include <linux/io.h>
43#include <linux/delay.h>
44#include <linux/i2c.h>
45#include <linux/platform_device.h>
46#include <sound/soc.h>
47#include <sound/core.h>
48#include <sound/soc-dapm.h>
49#include <sound/control.h>
50#include <linux/time.h> /* For timing computations */
51#include "tlv320aic326x.h"
52#include "tlv320aic326x_mini-dsp.h"
53
54#include "base_main_Rate48_pps_driver.h"
55#include "second_rate_pps_driver.h"
56//#include "one_mic_aec_nc_latest.h"
57#ifdef CONFIG_MINI_DSP
58
59#ifdef REG_DUMP_MINIDSP
60static void aic3262_dump_page(struct i2c_client *i2c, u8 page);
61#endif
62
63/*
64 *****************************************************************************
65 * LOCAL STATIC DECLARATIONS
66 *****************************************************************************
67 */
68static int m_control_info(struct snd_kcontrol *kcontrol,
69 struct snd_ctl_elem_info *uinfo);
70static int m_control_get(struct snd_kcontrol *kcontrol,
71 struct snd_ctl_elem_value *ucontrol);
72static int m_control_put(struct snd_kcontrol *kcontrol,
73 struct snd_ctl_elem_value *ucontrol);
74
75/*
76 *****************************************************************************
77 * MINIDSP RELATED GLOBALS
78 *****************************************************************************
79 */
80/* The below variable is used to maintain the I2C Transactions
81 * to be carried out during miniDSP switching.
82 */
83 #if 1
84minidsp_parser_data dsp_parse_data[MINIDSP_PARSER_ARRAY_SIZE*2];
85
86struct i2c_msg i2c_transaction[MINIDSP_PARSER_ARRAY_SIZE * 2];
87/* Total count of I2C Messages are stored in the i2c_count */
88int i2c_count;
89
90/* The below array is used to store the burst array for I2C Multibyte
91 * Operations
92 */
93minidsp_i2c_page i2c_page_array[MINIDSP_PARSER_ARRAY_SIZE];
94int i2c_page_count;
95#else
96minidsp_parser_data dsp_parse_data;
97
98struct i2c_msg i2c_transaction;
99/* Total count of I2C Messages are stored in the i2c_count */
100int i2c_count;
101
102/* The below array is used to store the burst array for I2C Multibyte
103 * Operations
104 */
105minidsp_i2c_page i2c_page_array;
106int i2c_page_count;
107#endif
108
109/* kcontrol structure used to register with ALSA Core layer */
110static struct snd_kcontrol_new snd_mux_controls[MAX_MUX_CONTROLS];
111
112/* mode variables */
113static int amode;
114static int dmode;
115
116/* k-control macros used for miniDSP related Kcontrols */
117#define SOC_SINGLE_VALUE_M(xmax, xinvert) \
118 ((unsigned long)&(struct soc_mixer_control) \
119 {.max = xmax, \
120 .invert = xinvert})
121#define SOC_SINGLE_M(xname, max, invert) \
122{\
123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
124 .info = m_control_info, .get = m_control_get,\
125 .put = m_control_put, \
126 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
127 .private_value = SOC_SINGLE_VALUE_M(max, invert) }
128#define SOC_SINGLE_AIC3262_M(xname) \
129{\
130 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
131 .info = m_control_info, .get = m_control_get,\
132 .put = m_control_put, \
133 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
134}
135
136/*
137 * aic3262_minidsp_controls
138 *
139 * Contains the list of the Kcontrol macros required for modifying the
140 * miniDSP behavior at run-time.
141 */
142static const struct snd_kcontrol_new aic3262_minidsp_controls[] = {
143 SOC_SINGLE_AIC3262_M("Minidsp mode") ,
144 SOC_SINGLE_AIC3262_M("ADC Adaptive mode Enable") ,
145 SOC_SINGLE_AIC3262_M("DAC Adaptive mode Enable") ,
146 SOC_SINGLE_AIC3262_M("Dump Regs Book0") ,
147 SOC_SINGLE_AIC3262_M("Verify minidsp program") ,
148};
149
150#ifdef REG_DUMP_MINIDSP
151/*
152 *----------------------------------------------------------------------------
153 * Function : aic3262_dump_page
154 * Purpose : Read and display one codec register page, for debugging purpose
155 *----------------------------------------------------------------------------
156 */
157static void aic3262_dump_page(struct i2c_client *i2c, u8 page)
158{
159 int i;
160 u8 data;
161 u8 test_page_array[256];
162
163 aic3262_change_page(codec, page);
164
165 data = 0x0;
166
167 i2c_master_send(i2c, data, 1);
168 i2c_master_recv(i2c, test_page_array, 128);
169
170 DBG("\n------- MINI_DSP PAGE %d DUMP --------\n", page);
171 for (i = 0; i < 128; i++)
172 DBG(KERN_INFO " [ %d ] = 0x%x\n", i, test_page_array[i]);
173
174}
175#endif
176
177/*
178 *----------------------------------------------------------------------------
179 * Function : update_kcontrols
180 * Purpose : Given the miniDSP process flow, this function reads the
181 * corresponding Page Numbers and then performs I2C Read for those
182 * Pages.
183 *----------------------------------------------------------------------------
184 */
185void update_kcontrols(struct snd_soc_codec *codec, int process_flow)
186{
187 int i, val1, array_size;
188 char **knames;
189 control *cntl;
190
191#if 0
192 if (process_flow == 1) {
193 knames = Second_Rate_MUX_control_names;
194 cntl = Second_Rate_MUX_controls;
195 array_size = ARRAY_SIZE(Second_Rate_MUX_controls);
196 } else {
197#endif
198 knames = main44_MUX_control_names;
199 cntl = main44_MUX_controls;
200 array_size = ARRAY_SIZE(main44_MUX_controls);
201// }
202
203 DBG(KERN_INFO "%s: ARRAY_SIZE = %d\tmode=%d\n", __func__,
204 array_size, process_flow);
205 for (i = 0; i < array_size; i++) {
206 aic3262_change_book(codec, cntl[i].control_book);
207 aic3262_change_page(codec, cntl[i].control_page);
208 val1 = i2c_smbus_read_byte_data(codec->control_data,
209 cntl[i].control_base);
210 snd_mux_controls[i].private_value = 0;
211 }
212}
213
214/*
215 *----------------------------------------------------------------------------
216 * Function : byte_i2c_array_transfer
217 * Purpose : Function used only for debugging purpose. This function will
218 * be used while switching miniDSP Modes register by register.
219 * This needs to be used only during development.
220 *-----------------------------------------------------------------------------
221 */
222 #if 1
223int byte_i2c_array_transfer(struct snd_soc_codec *codec,
224 reg_value *program_ptr,
225 int size)
226{
227 int j;
228 u8 buf[3];
229
230 for (j = 0; j < size; j++) {
231 /* Check if current Reg offset is zero */
232 if (program_ptr[j].reg_off == 0) {
233 /* Check for the Book Change Request */
234 if ((j < (size - 1)) &&
235 (program_ptr[j+1].reg_off == 127)) {
236 aic3262_change_book(codec,
237 program_ptr[j+1].reg_val);
238 /* Increment for loop counter across Book Change */
239 j++;
240 continue;
241 }
242 /* Check for the Page Change Request in Current book */
243 aic3262_change_page(codec, program_ptr[j].reg_val);
244 continue;
245 }
246
247 buf[AIC3262_REG_OFFSET_INDEX] = program_ptr[j].reg_off % 128;
248 buf[AIC3262_REG_DATA_INDEX] =
249 program_ptr[j].reg_val & AIC3262_8BITS_MASK;
250
251 if (codec->hw_write(codec->control_data, buf, 2) != 2) {
252 printk(KERN_ERR "Error in i2c write\n");
253 return -EIO;
254 }
255 }
256 aic3262_change_book(codec, 0);
257 return 0;
258}
259
260#else
261int byte_i2c_array_transfer(struct snd_soc_codec *codec,
262 reg_value *program_ptr,
263 int size)
264{
265 int j;
266 u8 buf[3];
267 printk(KERN_INFO "%s: started with array size %d\n", __func__, size);
268 for (j = 0; j < size; j++) {
269 /* Check if current Reg offset is zero */
270 buf[AIC3262_REG_OFFSET_INDEX] = program_ptr[j].reg_off % 128;
271 buf[AIC3262_REG_DATA_INDEX] =
272 program_ptr[j].reg_val & AIC3262_8BITS_MASK;
273
274 if (codec->hw_write(codec->control_data, buf, 2) != 2) {
275 printk(KERN_ERR "Error in i2c write\n");
276 return -EIO;
277 }
278 }
279 printk(KERN_INFO "%s: ended\n", __func__);
280 return 0;
281}
282#endif
283/*
284 *----------------------------------------------------------------------------
285 * Function : byte_i2c_array_read
286 * Purpose : This function is used to perform Byte I2C Read. This is used
287 * only for debugging purposes to read back the Codec Page
288 * Registers after miniDSP Configuration.
289 *----------------------------------------------------------------------------
290 */
291int byte_i2c_array_read(struct snd_soc_codec *codec,
292 reg_value *program_ptr, int size)
293{
294 int j;
295 u8 val1;
296 u8 cur_page = 0;
297 u8 cur_book = 0;
298 for (j = 0; j < size; j++) {
299 /* Check if current Reg offset is zero */
300 if (program_ptr[j].reg_off == 0) {
301 /* Check for the Book Change Request */
302 if ((j < (size - 1)) &&
303 (program_ptr[j+1].reg_off == 127)) {
304 aic3262_change_book(codec,
305 program_ptr[j+1].reg_val);
306 cur_book = program_ptr[j+1].reg_val;
307 /* Increment for loop counter across Book Change */
308 j++;
309 continue;
310 }
311 /* Check for the Page Change Request in Current book */
312 aic3262_change_page(codec, program_ptr[j].reg_val);
313 cur_page = program_ptr[j].reg_val;
314 continue;
315 }
316
317 val1 = i2c_smbus_read_byte_data(codec->control_data,
318 program_ptr[j].reg_off);
319 if (val1 < 0)
320 printk(KERN_ERR "Error in smbus read\n");
321
322 if(val1 != program_ptr[j].reg_val)
323 /*printk(KERN_INFO "mismatch [%d][%d][%d] = %x %x\n",
324 cur_book, cur_page, program_ptr[j].reg_off, val1, program_ptr[j].reg_val);*/
325 DBG(KERN_INFO "[%d][%d][%d]= %x\n",
326 cur_book, cur_page, program_ptr[j].reg_off, val1);
327 }
328 aic3262_change_book(codec, 0);
329 return 0;
330}
331
332/*
333 *----------------------------------------------------------------------------
334 * Function : minidsp_get_burst
335 * Purpose : Format one I2C burst for transfer from mini dsp program array.
336 * This function will parse the program array and get next burst
337 * data for doing an I2C bulk transfer.
338 *----------------------------------------------------------------------------
339 */
340static void
341minidsp_get_burst(reg_value *program_ptr,
342 int program_size,
343 minidsp_parser_data *parse_data)
344{
345 int index = parse_data->current_loc;
346 int burst_write_count = 0;
347
348 /*DBG("GET_BURST: start\n");*/
349 /* check if first location is page register, and populate page addr */
350 if (program_ptr[index].reg_off == 0) {
351 if ((index < (program_size - 1)) &&
352 (program_ptr[index+1].reg_off == 127)) {
353 parse_data->book_change = 1;
354 parse_data->book_no = program_ptr[index+1].reg_val;
355 index += 2;
356 goto finish_out;
357
358 }
359 parse_data->page_num = program_ptr[index].reg_val;
360 parse_data->burst_array[burst_write_count++] =
361 program_ptr[index].reg_off;
362 parse_data->burst_array[burst_write_count++] =
363 program_ptr[index].reg_val;
364 index++;
365 goto finish_out;
366 }
367
368 parse_data->burst_array[burst_write_count++] =
369 program_ptr[index].reg_off;
370 parse_data->burst_array[burst_write_count++] =
371 program_ptr[index].reg_val;
372 index++;
373
374 for (; index < program_size; index++) {
375 if (program_ptr[index].reg_off !=
376 (program_ptr[index - 1].reg_off + 1))
377 break;
378 else
379 parse_data->burst_array[burst_write_count++] =
380 program_ptr[index].reg_val;
381
382 }
383finish_out:
384 parse_data->burst_size = burst_write_count;
385 if (index == program_size)
386 /* parsing completed */
387 parse_data->current_loc = MINIDSP_PARSING_END;
388 else
389 parse_data->current_loc = index;
390 /*DBG("GET_BURST: end\n");*/
391}
392/*
393 *----------------------------------------------------------------------------
394 * Function : minidsp_i2c_multibyte_transfer
395 * Purpose : Function used to perform multi-byte I2C Writes. Used to configure
396 * the miniDSP Pages.
397 *----------------------------------------------------------------------------
398 */
399 #if 1
400int
401minidsp_i2c_multibyte_transfer(struct snd_soc_codec *codec,
402 reg_value *program_ptr,
403 int program_size)
404{
405 struct i2c_client *client = codec->control_data;
406
407 minidsp_parser_data parse_data;
408 int count = 0;
409
410#ifdef DEBUG_MINIDSP_LOADING
411 int i = 0, j = 0;
412#endif
413 /* point the current location to start of program array */
414 parse_data.current_loc = 0;
415 parse_data.page_num = 0;
416 parse_data.book_change = 0;
417 parse_data.book_no = 0;
418
419 DBG(KERN_INFO "size is : %d", program_size);
420 do {
421 do {
422 /* Get first burst data */
423 minidsp_get_burst(program_ptr, program_size,
424 &parse_data);
425 if (parse_data.book_change == 1)
426 break;
427 dsp_parse_data[count] = parse_data;
428
429 i2c_transaction[count].addr = client->addr;
430 i2c_transaction[count].flags =
431 client->flags & I2C_M_TEN;
432 i2c_transaction[count].len =
433 dsp_parse_data[count].burst_size;
434 i2c_transaction[count].buf =
435 dsp_parse_data[count].burst_array;
436
437#ifdef DEBUG_MINIDSP_LOADING
438 DBG(KERN_INFO
439 "i: %d\taddr: %d\tflags: %d\tlen: %d\tbuf:",
440 i, client->addr, client->flags & I2C_M_TEN,
441 dsp_parse_data[count].burst_size);
442
443 for (j = 0; j <= dsp_parse_data[count].burst_size; j++)
444 DBG(KERN_INFO "%x ",
445 dsp_parse_data[i].burst_array[j]);
446
447 DBG(KERN_INFO "\n\n");
448 i++;
449#endif
450
451 count++;
452 /* Proceed to the next burst reg_addr_incruence */
453 } while (parse_data.current_loc != MINIDSP_PARSING_END);
454
455 if (count > 0) {
456 if (i2c_transfer(client->adapter,
457 i2c_transaction, count) != count) {
458 printk(KERN_ERR "Write burst i2c data error!\n");
459 }
460 }
461 if (parse_data.book_change == 1) {
462 aic3262_change_book(codec, parse_data.book_no);
463 parse_data.book_change = 0;
464 }
465 } while (parse_data.current_loc != MINIDSP_PARSING_END);
466 aic3262_change_book(codec, 0);
467 return 0;
468}
469#else
470int
471minidsp_i2c_multibyte_transfer(struct snd_soc_codec *codec,
472 reg_value *program_ptr,
473 int program_size)
474{
475 struct i2c_client *client = codec->control_data;
476
477 minidsp_parser_data parse_data;
478 int count = 1;
479
480#ifdef DEBUG_MINIDSP_LOADING
481 int i = 0, j = 0;
482#endif
483 /* point the current location to start of program array */
484 parse_data.current_loc = 0;
485 parse_data.page_num = 0;
486 parse_data.book_change = 0;
487 parse_data.book_no = 0;
488
489 DBG(KERN_INFO "size is : %d", program_size);
490
491 do {
492 /* Get first burst data */
493 minidsp_get_burst(program_ptr, program_size,
494 &parse_data);
495
496 dsp_parse_data = parse_data;
497
498 i2c_transaction.addr = client->addr;
499 i2c_transaction.flags =
500 client->flags & I2C_M_TEN;
501 i2c_transaction.len =
502 dsp_parse_data.burst_size;
503 i2c_transaction.buf =
504 dsp_parse_data.burst_array;
505
506#ifdef DEBUG_MINIDSP_LOADING
507 DBG(KERN_INFO
508 "i: %d\taddr: %d\tflags: %d\tlen: %d\tbuf:",
509 i, client->addr, client->flags & I2C_M_TEN,
510 dsp_parse_data.burst_size);
511
512 for (j = 0; j <= dsp_parse_data.burst_size; j++)
513 printk( "%x ",
514 dsp_parse_data.burst_array[j]);
515
516 DBG(KERN_INFO "\n\n");
517 i++;
518#endif
519
520 if (i2c_transfer(client->adapter,
521 &i2c_transaction, count) != count) {
522 printk(KERN_ERR "Write burst i2c data error!\n");
523 }
524 if (parse_data.book_change == 1) {
525 aic3262_change_book(codec, parse_data.book_no);
526 parse_data.book_change = 0;
527 }
528 /* Proceed to the next burst reg_addr_incruence */
529 } while (parse_data.current_loc != MINIDSP_PARSING_END);
530
531 return 0;
532}
533#endif
534/*
535* Process_Flow Structure
536* Structure used to maintain the mapping of each PFW like the miniDSP_A
537* miniDSP_D array values and sizes. It also contains information about
538* the patches required for each patch.
539*/
540struct process_flow{
541 int init_size;
542 reg_value *miniDSP_init;
543 int A_size;
544 reg_value *miniDSP_A_values;
545 int D_size;
546 reg_value *miniDSP_D_values;
547 int post_size;
548 reg_value *miniDSP_post;
549 struct minidsp_config {
550 int a_patch_size;
551 reg_value *a_patch;
552 int d_patch_size;
553 reg_value *d_patch;
554 } configs[MAXCONFIG];
555
556} miniDSP_programs[] = {
557 {
558 ARRAY_SIZE(main44_REG_Section_init_program), main44_REG_Section_init_program,
559 ARRAY_SIZE(main44_miniDSP_A_reg_values),main44_miniDSP_A_reg_values,
560 ARRAY_SIZE(main44_miniDSP_D_reg_values),main44_miniDSP_D_reg_values,
561 ARRAY_SIZE(main44_REG_Section_post_program),main44_REG_Section_post_program,
562 {
563
564 { 0, 0, 0, 0},
565 { 0, 0, 0, 0},
566 { 0, 0, 0, 0},
567 { 0, 0, 0, 0},
568
569
570 },
571},
572 {
573 ARRAY_SIZE(base_speaker_SRS_REG_init_Section_program),base_speaker_SRS_REG_init_Section_program,
574 ARRAY_SIZE(base_speaker_SRS_miniDSP_A_reg_values),base_speaker_SRS_miniDSP_A_reg_values,
575 ARRAY_SIZE(base_speaker_SRS_miniDSP_D_reg_values),base_speaker_SRS_miniDSP_D_reg_values,
576 ARRAY_SIZE(base_speaker_SRS_REG_post_Section_program),base_speaker_SRS_REG_post_Section_program,
577
578 {
579 {0, 0, ARRAY_SIZE(SRS_ON_miniDSP_D_reg_values), SRS_ON_miniDSP_D_reg_values},
580 {0, 0, ARRAY_SIZE(SRS_OFF_miniDSP_D_reg_values),SRS_OFF_miniDSP_D_reg_values},
581 {0, 0, 0, 0},
582 {0, 0, 0, 0},
583 },
584},
585#if 0
586 {ARRAY_SIZE(spkr_srs_REG_Section_init_program),spkr_srs_REG_Section_init_program,
587 ARRAY_SIZE(spkr_srs_miniDSP_A_reg_values),spkr_srs_miniDSP_A_reg_values,
588 ARRAY_SIZE(spkr_srs_miniDSP_D_reg_values),spkr_srs_miniDSP_D_reg_values,
589 ARRAY_SIZE(spkr_srs_REG_Section_post_program),spkr_srs_REG_Section_post_program,
590 {
591 { 0, 0, 0, 0},
592 { 0, 0, 0, 0},
593 { 0, 0, 0, 0},
594 { 0, 0, 0, 0},
595
596 },
597},
598#endif
599};
600
601int
602set_minidsp_mode(struct snd_soc_codec *codec, int new_mode, int new_config)
603{
604
605 if (codec == NULL) {
606 printk(KERN_INFO "%s codec is NULL\n",__func__);
607 }
608 struct aic3262_priv *aic326x = snd_soc_codec_get_drvdata(codec);
609 struct snd_soc_dapm_context *dapm = &codec->dapm;
610 struct process_flow * pflows = &miniDSP_programs[new_mode];
611 u8 reg63, reg81, pll_pow, ndac_pow, mdac_pow, nadc_pow, madc_pow;
612
613 u8 adc_status,dac_status;
614 u8 reg, val;
615 u8 shift;
616 volatile u16 counter;
617
618 int (*ptransfer)(struct snd_soc_codec *codec,
619 reg_value *program_ptr,
620 int size);
621
622 printk("%s:New Switch mode = %d New Config= %d\n", __func__, new_mode,new_config);
623 if (new_mode >= ARRAY_SIZE(miniDSP_programs))
624 return 0; // error condition
625 if (new_config > MAXCONFIG)
626 return 0;
627#ifndef MULTIBYTE_I2C
628 ptransfer = byte_i2c_array_transfer;
629#else
630 ptransfer = minidsp_i2c_multibyte_transfer;
631#endif
632 if (new_mode != aic326x->process_flow) {
633
634 printk("== From PFW %d to PFW %d==\n", aic326x->process_flow , new_mode);
635
636 /* Change to book 0 page 0 and turn off the DAC and snd_soc_dapm_disable_piADC,
637 * while turning them down, poll for the power down completion.
638 */
639 aic3262_change_page(codec, 0);
640 aic3262_change_book(codec, 0);
641
642#if 0
643 reg63 = aic3262_read(codec, PASI_DAC_DP_SETUP);
644 aic3262_write(codec, PASI_DAC_DP_SETUP, (reg63 & ~0xC0));/*dac power down*/
645 mdelay (5);
646 counter = 0;
647 reg = DAC_FLAG_R1;
648
649 dac_status = aic3262_read(codec, reg);
650
651 do {
652 dac_status = snd_soc_read(codec, reg);
653 counter++;struct snd_soc_dapm_context *dapm
654 mdelay(5);
655 } while ((counter < 200) && ((dac_status & 0x88) == 1));
656 printk (KERN_INFO "#%s: Polled Register %d Bits set 0x%X counter %d\n",
657 __func__, reg, dac_status, counter);snd_soc_dapm_disable_pi
658 struct snd_soc_dapm_context *dapm
659 reg81= aic3262_read(codec, ADC_CHANNEL_POW);
660 aic3262_write(codec, ADC_CHANNEL_POW, (reg81 & ~0xC0));/*adc power down*/
661 mdelay (5);
662
663 adc_status=aic3262_read(codec,ADC_FLAG_R1);
664 counter = 0;
665 reg = ADC_FLAG_R1;
666 do {
667 adc_status = snd_soc_read(codec, reg);
668 counter++;
669 mdelay(5);
670 } while ((counter < 200) && ((adc_status & 0x44) == 1));
671
672 printk (KERN_INFO "#%s: Polled Register %d Bits set 0x%X counter %d\n",
673 __func__, reg, adc_status, counter);
674
675 dac_status = snd_soc_read(codec, DAC_FLAG_R1);
676 adc_status = snd_soc_read (codec, ADC_FLAG_R1);
677
678 printk (KERN_INFO "#%s: Initial DAC_STATUS 0x%x ADC_STATUS 0x%X\n",
679 __func__, dac_status, adc_status);
680
681#endif
682 /* Instead of hard-coding the switching off DAC and ADC, we will use the DAPM
683 * to switch off the Playback Paths and the ADC
684 */
685 snd_soc_dapm_disable_pin( dapm, "Headphone Jack");
686 snd_soc_dapm_disable_pin( dapm, "EarPiece");
687 snd_soc_dapm_disable_pin( dapm, "Int Spk");
688 snd_soc_dapm_disable_pin( dapm, "SPK out");
689 snd_soc_dapm_disable_pin( dapm, "Line Out");
690
691 snd_soc_dapm_disable_pin( dapm, "Mic Jack");
692 snd_soc_dapm_disable_pin( dapm, "Linein");
693 snd_soc_dapm_disable_pin( dapm, "Int Mic");
694
695 //snd_soc_dapm_disable_pin (codec, "Left DAC");
696 //snd_soc_dapm_disable_pin (codec, "Right DAC");
697 //snd_soc_dapm_disable_pin (codec, "Left ADC");
698 //snd_soc_dapm_disable_pin (codec, "Right ADC");
699 snd_soc_dapm_sync(dapm);
700 mdelay(10);
701
702 mdac_pow = aic3262_read(codec, MDAC_DIV_POW_REG);
703 aic3262_write(codec, MDAC_DIV_POW_REG, (mdac_pow & ~0x80));/*mdac power down*/
704 mdelay(5);
705 nadc_pow = aic3262_read(codec, MADC_DIV_POW_REG);
706 aic3262_write(codec, MADC_DIV_POW_REG, (nadc_pow & ~0x80));/*madc power down*/
707 mdelay(5);
708 pll_pow = aic3262_read(codec, PLL_PR_POW_REG);
709 aic3262_write(codec, PLL_PR_POW_REG, (pll_pow & ~0x80));/*pll power down*/
710 mdelay(5);
711 ndac_pow = aic3262_read(codec, NDAC_DIV_POW_REG);
712 aic3262_write(codec, NDAC_DIV_POW_REG, (ndac_pow & ~0x80)); /*ndac power down*/
713 mdelay(5);
714
715 dac_status = snd_soc_read(codec, DAC_FLAG_R1);
716 adc_status = snd_soc_read (codec, ADC_FLAG_R1);
717
718 printk (KERN_INFO "#%s: Before Switching DAC_STATUS 0x%x ADC_STATUS 0x%X\n",
719 __func__, dac_status, adc_status);
720
721 mdelay (10);
722 ptransfer(codec, pflows->miniDSP_init, pflows->init_size);
723 ptransfer(codec, pflows->miniDSP_A_values, pflows->A_size);
724 ptransfer(codec, pflows->miniDSP_D_values, pflows->D_size);
725 ptransfer(codec, pflows->miniDSP_post, pflows->post_size);
726
727
728 aic326x->process_flow = new_mode;
729
730 aic3262_change_page(codec, 0);
731 aic3262_change_book(codec, 0);
732#if 0
733
734 /* After the miniDSP Programming is completed, power up the DAC and ADC
735 * and poll for its power up operation.
736 */
737
738 aic3262_write(codec, PASI_DAC_DP_SETUP, reg63);/*reverting the old DAC values */
739 mdelay(5);
740
741 /* Poll for DAC Power-up first */
742 /* For DAC Power-up and Power-down event, we will poll for
743 * Book0 Page0 Register 37
744 */
745 reg = DAC_FLAG_R1;
746 counter = 0;
747 do {
748 dac_status = snd_soc_read(codec, reg);
749 counter++;
750 mdelay(5);
751 } while ((counter < 200) && ((dac_status & 0x88) == 0));
752
753 printk (KERN_INFO "#%s: Polled Register %d Bits set 0x%X counter %d\n",
754 __func__, reg, dac_status, counter);
755
756 aic3262_write(codec, ADC_CHANNEL_POW, reg81);/*reverting the old ADC values*/
757 mdelay (5);
758 /* For ADC Power-up and Power-down event, we will poll for
759 * Book0 Page0 Register 36
760 */
761 reg = ADC_FLAG_R1;
762 counter = 0;
763 do {
764 adc_status = snd_soc_read(codec, reg);
765 counter++;
766 mdelay(5);
767 } while ((counter < 200) && ((adc_status & 0x44) == 0));
768
769 printk (KERN_INFO "#%s: Polled Register %d Bits set 0x%X counter %d\n",
770 __func__, reg, adc_status, counter);
771 aic3262_write(codec, PLL_PR_POW_REG, pll_pow);/*reverting the old pll values*/
772 mdelay(10);
773
774 aic3262_write(codec, MDAC_DIV_POW_REG, mdac_pow);/*reverting the old mdac values*/
775 mdelay(5);
776 aic3262_write(codec, MADC_DIV_POW_REG, madc_pow);/*reverting the old madc values*/
777 mdelay(5);
778 aic3262_write(codec, NDAC_DIV_POW_REG, ndac_pow);/*reverting the old ndac values*/
779 mdelay(5);
780
781 /*if (new_config == 0) {
782 aic326x->current_config = 0;
783 return 0;
784 }
785 aic326x->current_config = -1;*/
786
787 //aic3262_change_book(codec, 0);
788 //aic3262_change_page(codec, 0);
789#endif
790 }
791
792#ifdef MULTICONFIG_SUPPORT
793 if (new_config < 0 )
794 return 0; // No configs supported in this pfw
795 if (new_config == aic326x->current_config)
796 return 0;
797 if (pflows->configs[new_config].a_patch_size || pflows->configs[new_config].d_patch_size)
798 minidsp_multiconfig(codec,
799 pflows->configs[new_config].a_patch, pflows->configs[new_config].a_patch_size,
800 pflows->configs[new_config].d_patch, pflows->configs[new_config].d_patch_size);
801#endif
802
803 aic326x->current_config = new_config;
804 aic3262_change_book( codec, 0);
805
806 DBG(KERN_INFO "%s: switch mode finished\n", __func__);
807 return 0;
808}
809
810/*
811 * i2c_verify
812 *
813 * Function used to validate the contents written into the miniDSP
814 * pages after miniDSP Configuration.
815*/
816int i2c_verify(struct snd_soc_codec *codec)
817{
818
819 DBG(KERN_INFO "#%s: Invoked.. Resetting to page 0\n", __func__);
820
821 aic3262_change_book(codec, 0);
822 DBG(KERN_INFO "#Reading reg_section_init_program\n");
823
824 byte_i2c_array_read(codec, main44_REG_Section_init_program,
825 ARRAY_SIZE(main44_REG_Section_init_program));
826
827 DBG(KERN_INFO "#Reading minidsp_A_reg_values\n");
828 byte_i2c_array_read(codec, main44_miniDSP_A_reg_values,
829 (main44_miniDSP_A_reg_values_COEFF_SIZE +
830 main44_miniDSP_A_reg_values_INST_SIZE));
831
832 DBG(KERN_INFO "#Reading minidsp_D_reg_values\n");
833 byte_i2c_array_read(codec, main44_miniDSP_D_reg_values,
834 (main44_miniDSP_D_reg_values_COEFF_SIZE +
835 main44_miniDSP_D_reg_values_INST_SIZE));
836
837 DBG(KERN_INFO "#Reading reg_section_post_program\n");
838 byte_i2c_array_read(codec, main44_REG_Section_post_program,
839 ARRAY_SIZE(main44_REG_Section_post_program));
840
841 aic3262_change_book(codec, 0);
842
843 DBG(KERN_INFO "i2c_verify completed\n");
844 return 0;
845}
846
847
848int change_codec_power_status(struct snd_soc_codec * codec, int off_restore, int power_mask)
849{
850 int minidsp_power_mask;
851 u8 dac_status;
852 u8 adc_status;
853
854 minidsp_power_mask = 0;
855
856 aic3262_change_page (codec, 0);
857 aic3262_change_book (codec, 0);
858
859
860 switch (off_restore) {
861
862 case 0: /* Power-off the Codec */
863 dac_status = snd_soc_read (codec, DAC_FLAG_R1);
864
865 if(dac_status & 0x88) {
866 minidsp_power_mask |= 0x1;
867 snd_soc_update_bits(codec, PASI_DAC_DP_SETUP, 0xC0, 0x0);
868
869 poll_dac(codec, 0x0, 0x0);
870 poll_dac(codec, 0x1, 0x0);
871 }
872
873 adc_status = snd_soc_read (codec, ADC_FLAG_R1);
874
875 if(adc_status & 0x44) {
876 minidsp_power_mask |= 0x2;
877 snd_soc_update_bits(codec, ADC_CHANNEL_POW, 0xC0, 0x0);
878
879 poll_adc(codec, 0x0, 0x0);
880 poll_adc(codec, 0x1, 0x0);
881 }
882 break;
883 case 1: /* For Restoring Codec to Previous Power State */
884
885 if(power_mask & 0x1) {
886
887 snd_soc_update_bits(codec, PASI_DAC_DP_SETUP, 0xC0, 0xC0);
888
889 poll_dac(codec, 0x0, 0x1);
890 poll_dac(codec, 0x1, 0x1);
891 }
892
893 if(power_mask & 0x2) {
894
895 snd_soc_update_bits(codec, ADC_CHANNEL_POW, 0xC0, 0xC0);
896
897 poll_adc(codec, 0x0, 0x1);
898 poll_adc(codec, 0x1, 0x1);
899 }
900 break;
901 default:
902 printk(KERN_ERR "#%s: Unknown Power State Requested..\n",
903 __func__);
904 }
905
906 return minidsp_power_mask;
907
908}
909
910/*
911 *----------------------------------------------------------------------------
912 * Function : boot_minidsp
913 * Purpose : for laoding the default minidsp mode for the first time .
914 *----------------------------------------------------------------------------
915 */
916int
917boot_minidsp(struct snd_soc_codec *codec, int new_mode)
918{
919 struct aic3262_priv *aic326x = snd_soc_codec_get_drvdata(codec);
920 struct process_flow * pflows = &miniDSP_programs[new_mode];
921 int minidsp_stat;
922
923 int (*ptransfer)(struct snd_soc_codec *codec,
924 reg_value *program_ptr,
925 int size);
926
927 DBG("%s: switch mode start\n", __func__);
928 if (new_mode >= ARRAY_SIZE(miniDSP_programs))
929 return 0; // error condition
930 if (new_mode == aic326x->process_flow)
931 return 0;
932
933
934#ifndef MULTIBYTE_I2C
935 ptransfer = byte_i2c_array_transfer;
936#else
937 ptransfer = minidsp_i2c_multibyte_transfer;
938#endif
939
940 minidsp_stat = change_codec_power_status (codec, 0x0, 0x3);
941
942 ptransfer(codec, pflows->miniDSP_init, pflows->init_size);
943 ptransfer(codec, pflows->miniDSP_A_values, pflows->A_size);
944 ptransfer(codec, pflows->miniDSP_D_values, pflows->D_size);
945 ptransfer(codec, pflows->miniDSP_post, pflows->post_size);
946
947 aic326x->process_flow = new_mode;
948
949 change_codec_power_status(codec, 1, minidsp_stat);
950
951 aic3262_change_page( codec,0);
952 aic3262_change_book( codec,0);
953
954 return 0;
955}
956
957/*
958 *----------------------------------------------------------------------------
959 * Function : aic3262_minidsp_program
960 * Purpose : Program mini dsp for AIC3262 codec chip. This routine is
961 * called from the aic3262 codec driver, if mini dsp programming
962 * is enabled.
963 *----------------------------------------------------------------------------
964 */
965int aic3262_minidsp_program(struct snd_soc_codec *codec)
966{
967 struct aic3262_priv *aic326x = snd_soc_codec_get_drvdata(codec);
968 DBG(KERN_INFO "#AIC3262: programming mini dsp\n");
969
970#if defined(PROGRAM_MINI_DSP_first)
971 #ifdef DEBUG
972 DBG("#Verifying book 0\n");
973 i2c_verify_book0(codec);
974#endif
975 aic3262_change_book(codec, 0);
976 boot_minidsp(codec, 1);
977 aic326x->process_flow = 0;
978 aic3262_change_book(codec, 0);
979#ifdef DEBUG
980 DBG("#verifying book 0\n");
981 i2c_verify_book0(codec);
982#endif
983#endif
984#if defined(PROGRAM_MINI_DSP_second)
985#ifdef DEBUG
986 DBG("#Verifying book 0\n");
987 aic3262_change_book(codec, 0);
988#endif
989 boot_minidsp(codec, 0);
990 aic326x->process_flow = 1;
991#ifdef DEBUG
992 DBG("#verifying book 0\n");
993 aic3262_change_book(codec, 0);
994#endif
995#endif
996 return 0;
997}
998/*
999 *----------------------------------------------------------------------------
1000 * Function : m_control_info
1001 * Purpose : This function is to initialize data for new control required to
1002 * program the AIC3262 registers.
1003 *
1004 *----------------------------------------------------------------------------
1005 */
1006static int m_control_info(struct snd_kcontrol *kcontrol,
1007 struct snd_ctl_elem_info *uinfo)
1008{
1009 uinfo->count = 1;
1010 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1011 uinfo->value.integer.min = 0;
1012 uinfo->value.integer.max = 1;
1013 return 0;
1014}
1015
1016/*
1017 *----------------------------------------------------------------------------
1018 * Function : m_control_get
1019 * Purpose : This function is to read data of new control for
1020 * program the AIC3262 registers.
1021 *
1022 *----------------------------------------------------------------------------
1023 */
1024static int m_control_get(struct snd_kcontrol *kcontrol,
1025 struct snd_ctl_elem_value *ucontrol)
1026{
1027 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1028 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1029 u32 val;
1030 u8 val1;
1031
1032 if (!strcmp(kcontrol->id.name, "Minidsp mode")) {
1033 val = aic3262->process_flow;
1034 ucontrol->value.integer.value[0] = val;
1035 DBG(KERN_INFO "control get : mode=%d\n", aic3262->process_flow);
1036 }
1037 if (!strcmp(kcontrol->id.name, "DAC Adaptive mode Enable")) {
1038 aic3262_change_book(codec, 80);
1039 val1 = i2c_smbus_read_byte_data(codec->control_data, 1);
1040 ucontrol->value.integer.value[0] = ((val1>>1)&0x01);
1041 DBG(KERN_INFO "control get : mode=%d\n", aic3262->process_flow);
1042 aic3262_change_book(codec,0);
1043 }
1044 if (!strcmp(kcontrol->id.name, "ADC Adaptive mode Enable")) {
1045 aic3262_change_book(codec, 40);
1046 val1 = i2c_smbus_read_byte_data(codec->control_data, 1);
1047 ucontrol->value.integer.value[0] = ((val1>>1)&0x01);
1048 DBG(KERN_INFO "control get : mode=%d\n", dmode);
1049 aic3262_change_book(codec,0);
1050 }
1051
1052 return 0;
1053}
1054
1055/*
1056 *----------------------------------------------------------------------------
1057 * Function : m_new_control_put
1058 * Purpose : new_control_put is called to pass data from user/application to
1059 * the driver.
1060 *
1061 *----------------------------------------------------------------------------
1062 */
1063static int m_control_put(struct snd_kcontrol *kcontrol,
1064 struct snd_ctl_elem_value *ucontrol)
1065{
1066 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1067 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1068
1069 u32 val;
1070 u8 val1;
1071 int mode = aic3262->process_flow;
1072
1073 DBG("n_control_put\n");
1074 val = ucontrol->value.integer.value[0];
1075 if (!strcmp(kcontrol->id.name, "Minidsp mode")) {
1076 DBG(KERN_INFO "\nMini dsp put\n mode = %d, val=%d\n",
1077 aic3262->process_flow, val);
1078 if (val != mode) {
1079 if (aic3262->mute_codec == 1) {
1080 i2c_verify_book0(codec);
1081 aic3262_change_book(codec, 0);
1082 boot_minidsp(codec, val);
1083
1084 aic3262_change_book(codec, 0);
1085 i2c_verify_book0(codec);
1086 /* update_kcontrols(codec, val);*/
1087 } else {
1088 printk(KERN_ERR
1089 " Cant Switch Processflows, Playback in progress");
1090 }
1091 }
1092 }
1093
1094 if (!strcmp(kcontrol->id.name, "DAC Adaptive mode Enable")) {
1095 DBG(KERN_INFO "\nMini dsp put\n mode = %d, val=%d\n",
1096 aic3262->process_flow, val);
1097 if (val != amode) {
1098 aic3262_change_book(codec, 80);
1099 val1 = i2c_smbus_read_byte_data(codec->control_data, 1);
1100 aic3262_write(codec, 1, (val1&0xfb)|(val<<1));
1101 aic3262_change_book(codec,0);
1102 }
1103 amode = val;
1104 }
1105
1106 if (!strcmp(kcontrol->id.name, "ADC Adaptive mode Enable")) {
1107 DBG(KERN_INFO "\nMini dsp put\n mode = %d, val=%d\n",
1108 aic3262->process_flow, val);
1109 if (val != dmode) {
1110 aic3262_change_book(codec, 40);
1111 val1 = i2c_smbus_read_byte_data(codec->control_data, 1);
1112 aic3262_write(codec, 1, (val1&0xfb)|(val<<1));
1113 aic3262_change_book(codec,0);
1114 }
1115 dmode = val;
1116 }
1117
1118 if (!strcmp(kcontrol->id.name, "Dump Regs Book0"))
1119 i2c_verify_book0(codec);
1120
1121#if 0
1122 if (!strcmp(kcontrol->id.name, "Verify minidsp program")) {
1123
1124 if (mode == 0) {
1125 DBG("Current mod=%d\nVerifying minidsp_D_regs", mode);
1126 byte_i2c_array_read(codec, main44_miniDSP_D_reg_values,
1127 (main44_miniDSP_D_reg_values_COEFF_SIZE +
1128 main44_miniDSP_D_reg_values_INST_SIZE));
1129 } else {
1130 byte_i2c_array_read(codec,
1131 Second_Rate_miniDSP_A_reg_values,
1132 (Second_Rate_miniDSP_A_reg_values_COEFF_SIZE +
1133 Second_Rate_miniDSP_A_reg_values_INST_SIZE));
1134 byte_i2c_array_read(codec,
1135 Second_Rate_miniDSP_D_reg_values,
1136 (Second_Rate_miniDSP_D_reg_values_COEFF_SIZE +
1137 Second_Rate_miniDSP_D_reg_values_INST_SIZE));
1138 }
1139 }
1140#endif
1141 DBG("\nmode = %d\n", mode);
1142 return mode;
1143}
1144
1145/************************** MUX CONTROL section *****************************/
1146/*
1147 *----------------------------------------------------------------------------
1148 * Function : __new_control_info_minidsp_mux
1149 * Purpose : info routine for mini dsp mux control amixer kcontrols
1150 *----------------------------------------------------------------------------
1151 */
1152static int __new_control_info_minidsp_mux(struct snd_kcontrol *kcontrol,
1153 struct snd_ctl_elem_info *uinfo)
1154{
1155 int index,index2;
1156 int ret_val = -1;
1157
1158
1159 for (index = 0; index < ARRAY_SIZE(main44_MUX_controls); index++) {
1160 if (strstr(kcontrol->id.name, main44_MUX_control_names[index]))
1161 break;
1162 }
1163 if (index < ARRAY_SIZE(main44_MUX_controls))
1164 {
1165 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1166 uinfo->count = 1;
1167 uinfo->value.integer.min = MIN_MUX_CTRL;
1168 uinfo->value.integer.max = MAX_MUX_CTRL;
1169 ret_val = 0;
1170 }
1171
1172 #if 1
1173 else{
1174 printk(" The second rate kcontrol id name is====== %s\n",kcontrol->id.name);
1175
1176
1177 for (index2 = 0; index < ARRAY_SIZE(base_speaker_SRS_MUX_controls); index2++) {
1178 if (strstr(kcontrol->id.name, base_speaker_SRS_MUX_control_names[index2]))
1179 break;
1180 }
1181 if (index < ARRAY_SIZE(base_speaker_SRS_MUX_controls))
1182 {
1183 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1184 uinfo->count = 1;
1185 uinfo->value.integer.min = MIN_MUX_CTRL;
1186 uinfo->value.integer.max = MAX_MUX_CTRL;
1187 ret_val = 0;
1188 }
1189 }
1190
1191 #endif
1192
1193 return ret_val;
1194}
1195
1196/*
1197 *----------------------------------------------------------------------------
1198 * Function : __new_control_get_minidsp_mux
1199 *
1200 * Purpose : get routine for mux control amixer kcontrols,
1201 * read current register values to user.
1202 * Used for for mini dsp 'MUX control' amixer controls.
1203 *----------------------------------------------------------------------------
1204 */
1205static int __new_control_get_minidsp_mux(struct snd_kcontrol *kcontrol,
1206 struct snd_ctl_elem_value *ucontrol)
1207{
1208
1209 ucontrol->value.integer.value[0] = kcontrol->private_value;
1210 return 0;
1211}
1212
1213/*
1214 *----------------------------------------------------------------------------
1215 * Function : __new_control_put_minidsp_mux
1216 *
1217 * Purpose : put routine for amixer kcontrols, write user values to registers
1218 * values. Used for for mini dsp 'MUX control' amixer controls.
1219 *----------------------------------------------------------------------------
1220 */
1221static int __new_control_put_minidsp_mux(struct snd_kcontrol *kcontrol,
1222 struct snd_ctl_elem_value *ucontrol)
1223{
1224 u8 data[MUX_CTRL_REG_SIZE + 1];
1225 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1226 int index = 1;
1227 int user_value = ucontrol->value.integer.value[0];
1228 struct i2c_client *i2c;
1229 u8 value[2], swap_reg_pre, swap_reg_post;
1230 u8 page;
1231 int ret_val = -1, array_size;
1232 control *array;
1233 char **array_names;
1234 char *control_name, *control_name1, *control_name2;
1235 struct aic3262_priv *aic326x = snd_soc_codec_get_drvdata(codec);
1236 i2c = codec->control_data;
1237
1238
1239
1240 if (aic326x->process_flow == 0) {
1241 DBG("#the current process flow is %d", aic326x->process_flow);
1242 array = main44_MUX_controls;
1243 array_size = ARRAY_SIZE(main44_MUX_controls);
1244 array_names = main44_MUX_control_names;
1245 control_name = "Stereo_Mux_TwoToOne_1";
1246 control_name1 = "Mono_Mux_1_1";
1247 }
1248
1249#if 0
1250
1251 /* Configure only for process flow 1 controls */
1252 if (strcmp(kcontrol->id.name, control_name) &&
1253 strcmp(kcontrol->id.name, control_name1))
1254 return 0;
1255 } else {
1256 array = Second_Rate_MUX_controls;
1257 array_size = ARRAY_SIZE(Second_Rate_MUX_controls);
1258 array_names = Second_Rate_MUX_control_names;
1259 control_name = "Stereo_Mux_TwoToOne_1_Second";
1260 control_name1 = "Mono_Mux_1_Second";
1261 control_name2 = "Mono_Mux_4_Second";
1262
1263 /* Configure only for process flow 2 controls */
1264 if (strcmp(kcontrol->id.name, control_name1) &&
1265 strcmp(kcontrol->id.name, control_name2))
1266 return 0;
1267 }
1268
1269#endif
1270
1271 page = array[index].control_page;
1272
1273 DBG("#user value = 0x%x\n", user_value);
1274 for (index = 0; index < array_size; index++) {
1275 if (strstr(kcontrol->id.name, array_names[index]))
1276 break;
1277 }
1278 if (index < array_size) {
1279 DBG(KERN_INFO "#Index %d Changing to Page %d\n", index,
1280 array[index].control_page);
1281
1282 aic3262_change_book(codec,
1283 array[index].control_book);
1284 aic3262_change_page(codec,
1285 array[index].control_page);
1286
1287 if (!strcmp(array_names[index], control_name)) {
1288 if (user_value > 0) {
1289 data[1] = 0x00;
1290 data[2] = 0x00;
1291 data[3] = 0x00;
1292 } else {
1293 data[1] = 0xFF;
1294 data[2] = 0xFf;
1295 data[3] = 0xFF;
1296 }
1297 } else {
1298 if (user_value > 0) {
1299 data[1] =
1300 (u8) ((user_value >> 16) &
1301 AIC3262_8BITS_MASK);
1302 data[2] =
1303 (u8) ((user_value >> 8) &
1304 AIC3262_8BITS_MASK);
1305 data[3] =
1306 (u8)((user_value) & AIC3262_8BITS_MASK);
1307 }
1308 }
1309 /* start register address */
1310 data[0] = array[index].control_base;
1311
1312 DBG(KERN_INFO
1313 "#Writing %d %d %d \r\n", data[0], data[1], data[2]);
1314
1315 ret_val = i2c_master_send(i2c, data, MUX_CTRL_REG_SIZE + 1);
1316
1317 if (ret_val != MUX_CTRL_REG_SIZE + 1)
1318 printk(KERN_ERR "i2c_master_send transfer failed\n");
1319 else {
1320 /* store the current level */
1321 kcontrol->private_value = user_value;
1322 ret_val = 0;
1323 /* Enable adaptive filtering for ADC/DAC */
1324 }
1325
1326 /* Perform a BUFFER SWAP Command. Check if we are currently not
1327 * in Page 8, if so, swap to Page 8 first
1328 */
1329
1330 value[0] = 1;
1331
1332 if (i2c_master_send(i2c, value, 1) != 1)
1333 printk(KERN_ERR "Can not write register address\n");
1334
1335 /* Read the Value of the Page 8 Register 1 which controls the
1336 Adaptive Switching Mode */
1337 if (i2c_master_recv(i2c, value, 1) != 1)
1338 printk(KERN_ERR "Can not read codec registers\n");
1339
1340 swap_reg_pre = value[0];
1341 /* Write the Register bit updates */
1342 value[1] = value[0] | 1;
1343 value[0] = 1;
1344
1345 if (i2c_master_send(i2c, value, 2) != 2)
1346 printk(KERN_ERR "Can not write register address\n");
1347
1348 value[0] = 1;
1349 /* verify buffer swap */
1350 if (i2c_master_send(i2c, value, 1) != 1)
1351 printk(KERN_ERR "Can not write register address\n");
1352
1353 /* Read the Value of the Page 8 Register 1 which controls the
1354 Adaptive Switching Mode */
1355 if (i2c_master_recv(i2c, &swap_reg_post, 1) != 1)
1356 printk(KERN_ERR "Can not read codec registers\n");
1357
1358 if ((swap_reg_pre == 4 && swap_reg_post == 6)
1359 || (swap_reg_pre == 6 && swap_reg_post == 4))
1360 DBG("Buffer swap success\n");
1361 else
1362 printk(KERN_ERR
1363 "Buffer swap...FAILED\nswap_reg_pre=%x, \
1364 swap_reg_post=%x\n", swap_reg_pre, swap_reg_post);
1365
1366 }
1367 /* update the new buffer value in the old, just swapped out buffer */
1368 aic3262_change_book(codec, array[index].control_book);
1369 aic3262_change_page(codec, array[index].control_page);
1370 ret_val = i2c_master_send(i2c, data, MUX_CTRL_REG_SIZE + 1);
1371 ret_val = 0;
1372
1373 aic3262_change_book(codec, 0);
1374 return ret_val;
1375}
1376
1377/*
1378 *----------------------------------------------------------------------------
1379 * Function : minidsp_mux_ctrl_mixer_controls
1380 *
1381 * Purpose : Add amixer kcontrols for mini dsp mux controls,
1382 *----------------------------------------------------------------------------
1383 */
1384static int minidsp_mux_ctrl_mixer_controls(struct snd_soc_codec *codec,
1385 int size, control *cntl,
1386 char **name)
1387{
1388 int i, err;
1389 int val1;
1390
1391 printk("%d mixer controls for mini dsp MUX\n", size);
1392 if (size) {
1393 for (i = 0; i < size; i++) {
1394
1395 snd_mux_controls[i].name = name[i];
1396 snd_mux_controls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1397 snd_mux_controls[i].access =
1398 SNDRV_CTL_ELEM_ACCESS_READWRITE;
1399 snd_mux_controls[i].info =
1400 __new_control_info_minidsp_mux;
1401 snd_mux_controls[i].get = __new_control_get_minidsp_mux;
1402 snd_mux_controls[i].put = __new_control_put_minidsp_mux;
1403 /*
1404 * TBD: read volume reg and update the index number
1405 */
1406 aic3262_change_book(codec, cntl[i].control_book);
1407 aic3262_change_page(codec, cntl[i].control_page);
1408 val1 = i2c_smbus_read_byte_data(codec->control_data,
1409 cntl[i].control_base);
1410 DBG(KERN_INFO "Control data %x\n", val1);
1411 /*
1412 if( val1 >= 0 )
1413 snd_mux_controls[i].private_value = val1;
1414 else
1415 snd_mux_controls[i].private_value = 0;
1416 */
1417 DBG(KERN_INFO
1418 "the value of amixer control mux=%d", val1);
1419 if (val1 >= 0 && val1 != 255)
1420 snd_mux_controls[i].private_value = val1;
1421 else
1422 snd_mux_controls[i].private_value = 0;
1423
1424 snd_mux_controls[i].count = 0;
1425
1426 err = snd_ctl_add(codec->card->snd_card,
1427 snd_ctl_new1(&snd_mux_controls[i],
1428 codec));
1429 if (err < 0)
1430 printk(KERN_ERR
1431 "%s:Invalid control %s\n", __FILE__,
1432 snd_mux_controls[i].name);
1433 }
1434 }
1435 return 0;
1436}
1437
1438/*------------------------- Volume Controls -----------------------*/
1439static int volume_lite_table[] = {
1440
1441 0x00000D, 0x00000E, 0x00000E, 0x00000F,
1442 0x000010, 0x000011, 0x000012, 0x000013,
1443 0x000015, 0x000016, 0x000017, 0x000018,
1444 0x00001A, 0x00001C, 0x00001D, 0x00001F,
1445 0x000021, 0x000023, 0x000025, 0x000027,
1446 0x000029, 0x00002C, 0x00002F, 0x000031,
1447 0x000034, 0x000037, 0x00003B, 0x00003E,
1448 0x000042, 0x000046, 0x00004A, 0x00004F,
1449 0x000053, 0x000058, 0x00005D, 0x000063,
1450 0x000069, 0x00006F, 0x000076, 0x00007D,
1451 0x000084, 0x00008C, 0x000094, 0x00009D,
1452 0x0000A6, 0x0000B0, 0x0000BB, 0x0000C6,
1453 0x0000D2, 0x0000DE, 0x0000EB, 0x0000F9,
1454 0x000108, 0x000118, 0x000128, 0x00013A,
1455 0x00014D, 0x000160, 0x000175, 0x00018B,
1456 0x0001A3, 0x0001BC, 0x0001D6, 0x0001F2,
1457 0x000210, 0x00022F, 0x000250, 0x000273,
1458 0x000298, 0x0002C0, 0x0002E9, 0x000316,
1459 0x000344, 0x000376, 0x0003AA, 0x0003E2,
1460 0x00041D, 0x00045B, 0x00049E, 0x0004E4,
1461 0x00052E, 0x00057C, 0x0005D0, 0x000628,
1462 0x000685, 0x0006E8, 0x000751, 0x0007C0,
1463 0x000836, 0x0008B2, 0x000936, 0x0009C2,
1464 0x000A56, 0x000AF3, 0x000B99, 0x000C49,
1465 0x000D03, 0x000DC9, 0x000E9A, 0x000F77,
1466 0x001062, 0x00115A, 0x001262, 0x001378,
1467 0x0014A0, 0x0015D9, 0x001724, 0x001883,
1468 0x0019F7, 0x001B81, 0x001D22, 0x001EDC,
1469 0x0020B0, 0x0022A0, 0x0024AD, 0x0026DA,
1470 0x002927, 0x002B97, 0x002E2D, 0x0030E9,
1471 0x0033CF, 0x0036E1, 0x003A21, 0x003D93,
1472 0x004139, 0x004517, 0x00492F, 0x004D85,
1473 0x00521D, 0x0056FA, 0x005C22, 0x006197,
1474 0x006760, 0x006D80, 0x0073FD, 0x007ADC,
1475 0x008224, 0x0089DA, 0x009205, 0x009AAC,
1476 0x00A3D7, 0x00B7D4, 0x00AD8C, 0x00C2B9,
1477 0x00CE43, 0x00DA7B, 0x00E76E, 0x00F524,
1478 0x0103AB, 0x01130E, 0x01235A, 0x01349D,
1479 0x0146E7, 0x015A46, 0x016ECA, 0x018486,
1480 0x019B8C, 0x01B3EE, 0x01CDC3, 0x01E920,
1481 0x02061B, 0x0224CE, 0x024553, 0x0267C5,
1482 0x028C42, 0x02B2E8, 0x02DBD8, 0x030736,
1483 0x033525, 0x0365CD, 0x039957, 0x03CFEE,
1484 0x0409C2, 0x044703, 0x0487E5, 0x04CCA0,
1485 0x05156D, 0x05628A, 0x05B439, 0x060ABF,
1486 0x066666, 0x06C77B, 0x072E50, 0x079B3D,
1487 0x080E9F, 0x0888D7, 0x090A4D, 0x09936E,
1488 0x0A24B0, 0x0ABE8D, 0x0B6188, 0x0C0E2B,
1489 0x0CC509, 0x0D86BD, 0x0E53EB, 0x0F2D42,
1490 0x101379, 0x110754, 0x1209A3, 0x131B40,
1491 0x143D13, 0x157012, 0x16B543, 0x180DB8,
1492 0x197A96, 0x1AFD13, 0x1C9676, 0x1E481C,
1493 0x201373, 0x21FA02, 0x23FD66, 0x261F54,
1494 0x28619A, 0x2AC625, 0x2D4EFB, 0x2FFE44,
1495 0x32D646, 0x35D96B, 0x390A41, 0x3C6B7E,
1496 0x400000, 0x43CAD0, 0x47CF26, 0x4C106B,
1497 0x50923B, 0x55586A, 0x5A6703, 0x5FC253,
1498 0x656EE3, 0x6B7186, 0x71CF54, 0x788DB4,
1499 0x7FB260,
1500};
1501
1502static struct snd_kcontrol_new snd_vol_controls[MAX_VOLUME_CONTROLS];
1503/*
1504 *----------------------------------------------------------------------------
1505 * Function : __new_control_info_main44_minidsp_volume
1506 * Purpose : info routine for volumeLite amixer kcontrols
1507 *----------------------------------------------------------------------------
1508 */
1509
1510static int
1511__new_control_info_minidsp_volume(struct snd_kcontrol *kcontrol,
1512 struct snd_ctl_elem_info *uinfo)
1513{
1514 int index, index8;
1515 int ret_val = -1;
1516
1517 for (index = 0; index < ARRAY_SIZE(main44_VOLUME_controls); index++) {
1518 if (strstr
1519 (kcontrol->id.name, main44_VOLUME_control_names[index]))
1520 break;
1521 }
1522
1523 for (index8 = 0; index8 < ARRAY_SIZE(base_speaker_SRS_VOLUME_controls);
1524 index8++) {
1525 if (strstr
1526 (kcontrol->id.name,
1527 base_speaker_SRS_VOLUME_control_names[index]))
1528 break;
1529 }
1530
1531 if ((index < ARRAY_SIZE(main44_VOLUME_controls))
1532
1533 || (index8 < ARRAY_SIZE(base_speaker_SRS_VOLUME_controls))) {
1534 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1535 uinfo->count = 1;
1536 uinfo->value.integer.min = MIN_VOLUME;
1537 uinfo->value.integer.max = MAX_VOLUME;
1538 ret_val = 0;
1539 }
1540 return ret_val;
1541}
1542
1543/*
1544 *----------------------------------------------------------------------------
1545 * Function : __new_control_get_main44_minidsp_vol
1546 * Purpose : get routine for amixer kcontrols, read current register
1547 * values. Used for for mini dsp 'VolumeLite' amixer controls.
1548 *----------------------------------------------------------------------------
1549 */
1550static int
1551__new_control_get_minidsp_volume(struct snd_kcontrol *kcontrol,
1552 struct snd_ctl_elem_value *ucontrol)
1553{
1554 ucontrol->value.integer.value[0] = kcontrol->private_value;
1555 return 0;
1556}
1557
1558/*
1559 *----------------------------------------------------------------------------
1560 * Function : __new_control_put_main44_minidsp_volume
1561 * Purpose : put routine for amixer kcontrols, write user values to registers
1562 * values. Used for for mini dsp 'VolumeLite' amixer controls.
1563 *----------------------------------------------------------------------------
1564 */
1565static int
1566__new_control_put_minidsp_volume(struct snd_kcontrol *kcontrol,
1567 struct snd_ctl_elem_value *ucontrol)
1568{
1569 u8 data[4];
1570 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1571 int user_value = ucontrol->value.integer.value[0];
1572 struct i2c_client *i2c = codec->control_data;
1573 int ret_val = -1;
1574 int coeff;
1575 u8 value[2], swap_reg_pre, swap_reg_post;
1576 struct aic3262_priv *aic3262 = snd_soc_codec_get_drvdata(codec);
1577
1578 control *volume_controls = NULL;
1579 printk(KERN_INFO "user value = 0x%x\n", user_value);
1580
1581 if (aic3262->process_flow == 0)
1582 volume_controls = main44_VOLUME_controls;
1583
1584 else
1585 volume_controls = base_speaker_SRS_VOLUME_controls;
1586
1587
1588 aic3262_change_book(codec, volume_controls->control_book);
1589 aic3262_change_page(codec, volume_controls->control_page);
1590
1591 coeff = volume_lite_table[user_value << 1];
1592
1593 data[1] = (u8) ((coeff >> 16) & AIC3262_8BITS_MASK);
1594 data[2] = (u8) ((coeff >> 8) & AIC3262_8BITS_MASK);
1595 data[3] = (u8) ((coeff) & AIC3262_8BITS_MASK);
1596
1597 /* Start register address */
1598 data[0] = volume_controls->control_base;
1599 ret_val = i2c_master_send(i2c, data, VOLUME_REG_SIZE + 1);
1600 if (ret_val != VOLUME_REG_SIZE + 1)
1601 printk(KERN_ERR "i2c_master_send transfer failed\n");
1602 else {
1603 /* store the current level */
1604 kcontrol->private_value = user_value;
1605 ret_val = 0;
1606 }
1607 /* Initiate buffer swap */
1608 value[0] = 1;
1609
1610 if (i2c_master_send(i2c, value, 1) != 1)
1611 printk(KERN_ERR "Can not write register address\n");
1612
1613 /* Read the Value of the Page 8 Register 1 which controls the
1614 Adaptive Switching Mode */
1615 if (i2c_master_recv(i2c, value, 1) != 1)
1616 printk(KERN_ERR "Can not read codec registers\n");
1617
1618 swap_reg_pre = value[0];
1619 /* Write the Register bit updates */
1620 value[1] = value[0] | 1;
1621 value[0] = 1;
1622 if (i2c_master_send(i2c, value, 2) != 2)
1623 printk(KERN_ERR "Can not write register address\n");
1624
1625 value[0] = 1;
1626 /* verify buffer swap */
1627 if (i2c_master_send(i2c, value, 1) != 1)
1628 printk(KERN_ERR "Can not write register address\n");
1629
1630 /* Read the Value of the Page 8 Register 1 which controls the
1631 Adaptive Switching Mode */
1632 if (i2c_master_recv(i2c, &swap_reg_post, 1) != 1)
1633 printk(KERN_ERR "Can not read codec registers\n");
1634
1635 if ((swap_reg_pre == 4 && swap_reg_post == 6)
1636 || (swap_reg_pre == 6 && swap_reg_post == 4))
1637 DBG("Buffer swap success\n");
1638 else
1639 DBG("Buffer swap...FAILED\nswap_reg_pre=%x, swap_reg_post=%x\n",
1640 swap_reg_pre, swap_reg_post);
1641
1642 /* update the new buffer value in the old, just swapped out buffer */
1643 aic3262_change_book(codec, volume_controls->control_book);
1644 aic3262_change_page(codec, volume_controls->control_page);
1645 i2c_master_send(i2c, data, MUX_CTRL_REG_SIZE + 1);
1646
1647 aic3262_change_book(codec, 0);
1648
1649 return 0;
1650}
1651
1652/*
1653 *----------------------------------------------------------------------------
1654 * Function : minidsp_volume_main44_mixer_controls
1655 * Purpose : Add amixer kcontrols for mini dsp volume Lite controls,
1656 *----------------------------------------------------------------------------
1657 */
1658static int minidsp_volume_mixer_controls(struct snd_soc_codec *codec)
1659{
1660 int i, err, no_volume_controls;
1661 static char volume_control_name[MAX_VOLUME_CONTROLS][40];
1662
1663 /* ADD first process volume controls */
1664 no_volume_controls = ARRAY_SIZE(main44_VOLUME_controls);
1665
1666 printk(KERN_INFO " %d mixer controls for mini dsp 'volumeLite'\n",
1667 no_volume_controls);
1668
1669 if (no_volume_controls) {
1670
1671 for (i = 0; i < no_volume_controls; i++) {
1672 strcpy(volume_control_name[i],
1673 main44_VOLUME_control_names[i]);
1674 strcat(volume_control_name[i], VOLUME_KCONTROL_NAME);
1675
1676 printk(KERN_ERR "Volume controls: %s\n",
1677 volume_control_name[i]);
1678
1679 snd_vol_controls[i].name = volume_control_name[i];
1680 snd_vol_controls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1681 snd_vol_controls[i].access =
1682 SNDRV_CTL_ELEM_ACCESS_READWRITE;
1683 snd_vol_controls[i].info =
1684 __new_control_info_minidsp_volume;
1685 snd_vol_controls[i].get =
1686 __new_control_get_minidsp_volume;
1687 snd_vol_controls[i].put =
1688 __new_control_put_minidsp_volume;
1689 /*
1690 * TBD: read volume reg and update the index number
1691 */
1692 snd_vol_controls[i].private_value = 0;
1693 snd_vol_controls[i].count = 0;
1694
1695 err = snd_ctl_add(codec->card->snd_card,
1696 snd_ctl_new1(&snd_vol_controls[i],
1697 codec));
1698 if (err < 0) {
1699 printk(KERN_ERR
1700 "%s:Invalid control %s\n", __FILE__,
1701 snd_vol_controls[i].name);
1702 }
1703 }
1704 }
1705
1706
1707 /* ADD second process volume controls */
1708 no_volume_controls = ARRAY_SIZE(base_speaker_SRS_VOLUME_controls);
1709
1710 printk(KERN_ERR " %d mixer controls for mini dsp 'volumeLite'\n",
1711 no_volume_controls);
1712
1713 if (no_volume_controls) {
1714
1715 for (i = 0; i < no_volume_controls; i++) {
1716 strcpy(volume_control_name[i],
1717 base_speaker_SRS_VOLUME_control_names[i]);
1718 strcat(volume_control_name[i], VOLUME_KCONTROL_NAME);
1719
1720 printk(KERN_ERR "Volume controls: %s\n",
1721 volume_control_name[i]);
1722
1723 snd_vol_controls[i].name = volume_control_name[i];
1724 snd_vol_controls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1725 snd_vol_controls[i].access =
1726 SNDRV_CTL_ELEM_ACCESS_READWRITE;
1727 snd_vol_controls[i].info =
1728 __new_control_info_minidsp_volume;
1729 snd_vol_controls[i].get =
1730 __new_control_get_minidsp_volume;
1731 snd_vol_controls[i].put =
1732 __new_control_put_minidsp_volume;
1733 /*
1734 * TBD: read volume reg and update the index number
1735 */
1736 snd_vol_controls[i].private_value = 0;
1737 snd_vol_controls[i].count = 0;
1738
1739 err = snd_ctl_add(codec->card->snd_card,
1740 snd_ctl_new1(&snd_vol_controls[i],
1741 codec));
1742 if (err < 0) {
1743 printk(KERN_ERR
1744 "%s:Invalid control %s\n", __FILE__,
1745 snd_vol_controls[i].name);
1746 }
1747 }
1748 }
1749
1750 return 0;
1751}
1752
1753/*
1754 *--------------------------------------------------------------------------
1755 * Function : aic3262_add_minidsp_controls
1756 * Purpose : Configures the AMIXER Control Interfaces that can be exercised by
1757 * the user at run-time. Utilizes the the snd_adaptive_controls[]
1758 * array to specify two run-time controls.
1759 *---------------------------------------------------------------------------
1760 */
1761int aic3262_add_minidsp_controls(struct snd_soc_codec *codec)
1762{
1763#ifdef ADD_MINI_DSP_CONTROLS
1764 int i, err, no_mux_controls,no_mux_controls1;
1765 /* add mode k control */
1766 for (i = 0; i < ARRAY_SIZE(aic3262_minidsp_controls); i++) {
1767 err = snd_ctl_add(codec->card->snd_card,
1768 snd_ctl_new1(&aic3262_minidsp_controls[i], codec));
1769 if (err < 0) {
1770 printk(KERN_ERR "Invalid control\n");
1771 return err;
1772 }
1773 }
1774
1775
1776 /* add mux controls */
1777 no_mux_controls = ARRAY_SIZE(main44_MUX_controls);
1778 minidsp_mux_ctrl_mixer_controls(codec, no_mux_controls,
1779 main44_MUX_controls, main44_MUX_control_names);
1780
1781
1782 no_mux_controls1 = ARRAY_SIZE(base_speaker_SRS_MUX_controls);
1783 minidsp_mux_ctrl_mixer_controls(codec, no_mux_controls1,
1784 base_speaker_SRS_MUX_controls, base_speaker_SRS_MUX_control_names);
1785
1786
1787 /* add volume controls*/
1788 minidsp_volume_mixer_controls(codec);
1789#endif /* ADD_MINI_DSP_CONTROLS */
1790 return 0;
1791}
1792
1793MODULE_DESCRIPTION("ASoC TLV320AIC3262 miniDSP driver");
1794MODULE_AUTHOR("Y Preetam Sashank Reddy <preetam@mistralsolutions.com>");
1795MODULE_LICENSE("GPL");
1796#endif /* End of CONFIG_MINI_DSP */