diff options
Diffstat (limited to 'sound/soc/omap/abe/abe_seq.c')
-rw-r--r-- | sound/soc/omap/abe/abe_seq.c | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/sound/soc/omap/abe/abe_seq.c b/sound/soc/omap/abe/abe_seq.c new file mode 100644 index 0000000..6ae2aa5 --- /dev/null +++ b/sound/soc/omap/abe/abe_seq.c @@ -0,0 +1,308 @@ +/* + + This file is provided under a dual BSD/GPLv2 license. When using or + redistributing this file, you may do so under either license. + + GPL LICENSE SUMMARY + + Copyright(c) 2010-2011 Texas Instruments Incorporated, + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + 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. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + The full GNU General Public License is included in this distribution + in the file called LICENSE.GPL. + + BSD LICENSE + + Copyright(c) 2010-2011 Texas Instruments Incorporated, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "abe_legacy.h" + +#include "abe_mem.h" + +extern struct omap_abe *abe; +extern u32 abe_irq_pingpong_player_id; + +/** + * abe_null_subroutine + * + */ +void abe_null_subroutine_0(void) +{ +} +void abe_null_subroutine_2(u32 a, u32 b) +{ +} +void abe_null_subroutine_4(u32 a, u32 b, u32 c, u32 d) +{ +} +/** + * abe_init_subroutine_table - initializes the default table of pointers + * to subroutines + * + * initializes the default table of pointers to subroutines + * + */ +void abe_init_subroutine_table(void) +{ + u32 id; + /* reset the table's pointers */ + abe_subroutine_write_pointer = 0; + /* the first index is the NULL task */ + abe_add_subroutine(&id, (abe_subroutine2) abe_null_subroutine_2, + SUB_0_PARAM, (u32 *) 0); + /* write mixer has 4 parameters */ + abe_add_subroutine(&(abe_subroutine_id[SUB_WRITE_MIXER]), + (abe_subroutine2) abe_write_mixer, SUB_4_PARAM, + (u32 *) 0); + /* ping-pong player IRQ */ + abe_add_subroutine(&abe_irq_pingpong_player_id, + (abe_subroutine2) abe_null_subroutine_0, SUB_0_PARAM, + (u32 *) 0); +} +/** + * abe_add_subroutine + * @id: ABE port id + * @f: pointer to the subroutines + * @nparam: number of parameters + * @params: pointer to the psrameters + * + * add one function pointer more and returns the index to it + */ +void abe_add_subroutine(u32 *id, abe_subroutine2 f, u32 nparam, u32 *params) +{ + u32 i, i_found; + if ((abe_subroutine_write_pointer >= MAXNBSUBROUTINE) || + ((u32) f == 0)) { + omap_abe_dbg_error(abe, OMAP_ABE_ERR_SEQ, + ABE_PARAMETER_OVERFLOW); + } else { + /* search if this subroutine address was not already + * declared, then return the previous index + */ + for (i_found = abe_subroutine_write_pointer, i = 0; + i < abe_subroutine_write_pointer; i++) { + if (f == abe_all_subsubroutine[i]) + i_found = i; + } + if (i_found == abe_subroutine_write_pointer) { + *id = abe_subroutine_write_pointer; + abe_all_subsubroutine + [abe_subroutine_write_pointer] = (f); + abe_all_subroutine_params + [abe_subroutine_write_pointer] = params; + abe_all_subsubroutine_nparam + [abe_subroutine_write_pointer] = nparam; + abe_subroutine_write_pointer++; + } else { + abe_all_subroutine_params[i_found] = params; + *id = i_found; + } + } +} +/** + * abe_add_sequence + * @id: returned sequence index after pluging a new sequence + * (index in the tables) + * @s: sequence to be inserted + * + * Load a time-sequenced operations. + */ +void abe_add_sequence(u32 *id, abe_sequence_t *s) +{ + abe_seq_t *seq_src, *seq_dst; + u32 i, no_end_of_sequence_found; + seq_src = &(s->seq1); + seq_dst = &((abe_all_sequence[abe_sequence_write_pointer]).seq1); + if ((abe_sequence_write_pointer >= MAXNBSEQUENCE) || ((u32) s == 0)) { + omap_abe_dbg_error(abe, OMAP_ABE_ERR_SEQ, + ABE_PARAMETER_OVERFLOW); + } else { + *id = abe_subroutine_write_pointer; + /* copy the mask */ + (abe_all_sequence[abe_sequence_write_pointer]).mask = s->mask; + for (no_end_of_sequence_found = 1, i = 0; i < MAXSEQUENCESTEPS; + i++, seq_src++, seq_dst++) { + /* sequence copied line by line */ + (*seq_dst) = (*seq_src); + /* stop when the line start with time=(-1) */ + if ((*(s32 *) seq_src) == (-1)) { + /* stop when the line start with time=(-1) */ + no_end_of_sequence_found = 0; + break; + } + } + abe_subroutine_write_pointer++; + if (no_end_of_sequence_found) + omap_abe_dbg_error(abe, OMAP_ABE_ERR_API, + ABE_SEQTOOLONG); + } +} +/** + * abe_reset_one_sequence + * @id: sequence ID + * + * load default configuration for that sequence + * kill running activities + */ +void abe_reset_one_sequence(u32 id) +{ +} +/** + * abe_reset_all_sequence + * + * load default configuration for all sequences + * kill any running activities + */ +void omap_abe_reset_all_sequence(struct omap_abe *abe) +{ + u32 i; + abe_init_subroutine_table(); + /* arrange to have the first sequence index=0 to the NULL operation + sequence */ + abe_add_sequence(&i, (abe_sequence_t *) &seq_null); + /* reset the the collision protection mask */ + abe_global_sequence_mask = 0; + /* reset the pending sequences list */ + for (abe_nb_pending_sequences = i = 0; i < MAXNBSEQUENCE; i++) + abe_pending_sequences[i] = 0; +} +/** + * abe_call_subroutine + * @idx: index to the table of all registered Call-backs and subroutines + * + * run and log a subroutine + */ +void abe_call_subroutine(u32 idx, u32 p1, u32 p2, u32 p3, u32 p4) +{ + abe_subroutine0 f0; + abe_subroutine1 f1; + abe_subroutine2 f2; + abe_subroutine3 f3; + abe_subroutine4 f4; + u32 *params; + if (idx > MAXNBSUBROUTINE) + return; + switch (idx) { + /* call the subroutines defined at compilation time + (const .. sequences) */ +#if 0 + case SUB_WRITE_MIXER_DL1: + abe_write_mixer_dl1(p1, p2, p3) + abe_fprintf("write_mixer"); + break; +#endif + /* call the subroutines defined at execution time + (dynamic sequences) */ + default: + switch (abe_all_subsubroutine_nparam[idx]) { + case SUB_0_PARAM: + f0 = (abe_subroutine0) abe_all_subsubroutine[idx]; + (*f0) (); + break; + case SUB_1_PARAM: + f1 = (abe_subroutine1) abe_all_subsubroutine[idx]; + params = abe_all_subroutine_params + [abe_irq_pingpong_player_id]; + if (params != (u32 *) 0) + p1 = params[0]; + (*f1) (p1); + break; + case SUB_2_PARAM: + f2 = abe_all_subsubroutine[idx]; + params = abe_all_subroutine_params + [abe_irq_pingpong_player_id]; + if (params != (u32 *) 0) { + p1 = params[0]; + p2 = params[1]; + } + (*f2) (p1, p2); + break; + case SUB_3_PARAM: + f3 = (abe_subroutine3) abe_all_subsubroutine[idx]; + params = abe_all_subroutine_params + [abe_irq_pingpong_player_id]; + if (params != (u32 *) 0) { + p1 = params[0]; + p2 = params[1]; + p3 = params[2]; + } + (*f3) (p1, p2, p3); + break; + case SUB_4_PARAM: + f4 = (abe_subroutine4) abe_all_subsubroutine[idx]; + params = abe_all_subroutine_params + [abe_irq_pingpong_player_id]; + if (params != (u32 *) 0) { + p1 = params[0]; + p2 = params[1]; + p3 = params[2]; + p4 = params[3]; + } + (*f4) (p1, p2, p3, p4); + break; + default: + break; + } + } +} + +/** + * abe_set_sequence_time_accuracy + * @fast: fast counter + * @slow: slow counter + * + */ +abehal_status abe_set_sequence_time_accuracy(u32 fast, u32 slow) +{ + u32 data; + _log(ABE_ID_SET_SEQUENCE_TIME_ACCURACY, fast, slow, 0); + data = minimum(MAX_UINT16, fast / FW_SCHED_LOOP_FREQ_DIV1000); + omap_abe_mem_write(abe, OMAP_ABE_DMEM, OMAP_ABE_D_FASTCOUNTER_ADDR, + &data, sizeof(data)); + data = minimum(MAX_UINT16, slow / FW_SCHED_LOOP_FREQ_DIV1000); + omap_abe_mem_write(abe, OMAP_ABE_DMEM, OMAP_ABE_D_SLOWCOUNTER_ADDR, + &data, sizeof(data)); + return 0; +} +EXPORT_SYMBOL(abe_set_sequence_time_accuracy); |