mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-10 01:12:45 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
277
drivers/media/radio/s610/fm_rds.c
Executable file
277
drivers/media/radio/s610/fm_rds.c
Executable file
|
@ -0,0 +1,277 @@
|
|||
|
||||
#include "fm_low_struc.h"
|
||||
#include "radio-s610.h"
|
||||
#include "fm_rds.h"
|
||||
|
||||
void fm_rds_write_data(struct s610_radio *radio, u16 rds_data,
|
||||
fm_rds_block_type_enum blk_type, fm_host_rds_errors_enum errors)
|
||||
{
|
||||
u8 *buf_ptr;
|
||||
u16 usage;
|
||||
u16 capa;
|
||||
|
||||
/* API_ENTRY(radio);*/
|
||||
|
||||
capa = radio->low->rds_buffer->size;
|
||||
if (radio->low->rds_buffer->outdex
|
||||
> radio->low->rds_buffer->index)
|
||||
usage = radio->low->rds_buffer->size
|
||||
- radio->low->rds_buffer->outdex
|
||||
+ radio->low->rds_buffer->index;
|
||||
else
|
||||
usage = radio->low->rds_buffer->index
|
||||
- radio->low->rds_buffer->outdex;
|
||||
|
||||
if ((capa - usage) >= (HOST_RDS_BLOCK_SIZE * 4)) {
|
||||
buf_ptr = radio->low->rds_buffer->base
|
||||
+ radio->low->rds_buffer->index;
|
||||
|
||||
buf_ptr[HOST_RDS_BLOCK_FMT_LSB] = (u8)(rds_data & 0xff);
|
||||
buf_ptr[HOST_RDS_BLOCK_FMT_MSB] = (u8) (rds_data >> 8);
|
||||
|
||||
buf_ptr[HOST_RDS_BLOCK_FMT_STATUS] = (blk_type
|
||||
<< HOST_RDS_DATA_BLKTYPE_POSI)
|
||||
| (errors << HOST_RDS_DATA_ERRORS_POSI)
|
||||
| HOST_RDS_DATA_AVAIL_MASK;
|
||||
|
||||
/* Advances the buffer's index */
|
||||
radio->low->rds_buffer->index
|
||||
+= HOST_RDS_BLOCK_SIZE;
|
||||
|
||||
/* Check if the buffer's index wraps */
|
||||
if (radio->low->rds_buffer->index >=
|
||||
radio->low->rds_buffer->size) {
|
||||
radio->low->rds_buffer->index -=
|
||||
radio->low->rds_buffer->size;
|
||||
}
|
||||
|
||||
if (usage >= HOST_RDS_BLOCK_SIZE)
|
||||
radio->low->fm_state.status |= STATUS_MASK_RDS_AVA;
|
||||
|
||||
}
|
||||
|
||||
if (radio->low->fm_state.rds_mem_thresh != 0) {
|
||||
if (usage
|
||||
>= (radio->low->fm_state.rds_mem_thresh
|
||||
* HOST_RDS_BLOCK_SIZE)) {
|
||||
fm_set_flag_bits(radio, FLAG_BUF_FUL);
|
||||
radio->rds_cnt_mod++;
|
||||
if (!(radio->rds_cnt_mod % 100))
|
||||
APIEBUG(radio, ">N ");
|
||||
|
||||
radio->rds_n_count++;
|
||||
radio->rds_new = TRUE;
|
||||
atomic_set(&radio->is_rds_new, 1);
|
||||
wake_up_interruptible(&radio->core->rds_read_queue);
|
||||
}
|
||||
}
|
||||
|
||||
/* API_EXIT(radio);*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
u16 fm_rds_get_avail_bytes(struct s610_radio *radio)
|
||||
{
|
||||
u16 avail_bytes;
|
||||
|
||||
if (radio->low->rds_buffer->outdex >
|
||||
radio->low->rds_buffer->index)
|
||||
avail_bytes = (radio->low->rds_buffer->size
|
||||
- radio->low->rds_buffer->outdex
|
||||
+ radio->low->rds_buffer->index);
|
||||
else
|
||||
avail_bytes = (radio->low->rds_buffer->index
|
||||
- radio->low->rds_buffer->outdex);
|
||||
|
||||
return avail_bytes;
|
||||
}
|
||||
|
||||
|
||||
bool fm_read_rds_data(struct s610_radio *radio, u16 *buffer,
|
||||
u16 *size, u16 *blocks)
|
||||
{
|
||||
u16 avail_bytes;
|
||||
s16 avail_blocks;
|
||||
s16 orig_avail;
|
||||
u8 *buf_ptr;
|
||||
|
||||
if (radio->low->rds_buffer == NULL) {
|
||||
*size = 0;
|
||||
if (blocks)
|
||||
*blocks = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
orig_avail = avail_bytes = fm_rds_get_avail_bytes(radio);
|
||||
|
||||
if (avail_bytes > *size)
|
||||
avail_bytes = *size;
|
||||
|
||||
avail_blocks = avail_bytes / HOST_RDS_BLOCK_SIZE;
|
||||
avail_bytes = avail_blocks * HOST_RDS_BLOCK_SIZE;
|
||||
|
||||
if (avail_bytes == 0) {
|
||||
*size = 0;
|
||||
if (blocks)
|
||||
*blocks = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
buf_ptr = radio->low->rds_buffer->base
|
||||
+ radio->low->rds_buffer->outdex;
|
||||
(void) memcpy(buffer, buf_ptr, avail_bytes);
|
||||
|
||||
/* advances the buffer's outdex */
|
||||
radio->low->rds_buffer->outdex += avail_bytes;
|
||||
|
||||
/* Check if the buffer's outdex wraps */
|
||||
if (radio->low->rds_buffer->outdex >= radio->low->rds_buffer->size)
|
||||
radio->low->rds_buffer->outdex -= radio->low->rds_buffer->size;
|
||||
|
||||
if (orig_avail == avail_bytes) {
|
||||
buffer[(avail_blocks - 1) * HOST_RDS_BLOCK_SIZE
|
||||
+ HOST_RDS_BLOCK_FMT_STATUS] &=
|
||||
~HOST_RDS_DATA_AVAIL_MASK;
|
||||
radio->low->fm_state.status &= ~STATUS_MASK_RDS_AVA;
|
||||
}
|
||||
|
||||
*size = avail_bytes; /* number of bytes read */
|
||||
|
||||
if (blocks)
|
||||
*blocks = avail_bytes / HOST_RDS_BLOCK_SIZE;
|
||||
|
||||
/* Update RDS flags */
|
||||
if ((avail_bytes / HOST_RDS_BLOCK_SIZE)
|
||||
< radio->low->fm_state.rds_mem_thresh)
|
||||
fm_clear_flag_bits(radio, FLAG_BUF_FUL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void fm_rds_change_state(struct s610_radio *radio,
|
||||
fm_rds_state_enum new_state)
|
||||
{
|
||||
fm_rds_state_enum old_state =
|
||||
(fm_rds_state_enum) radio->low->fm_rds_state.current_state;
|
||||
|
||||
radio->low->fm_rds_state.current_state = new_state;
|
||||
|
||||
if ((old_state == RDS_STATE_FULL_SYNC)
|
||||
&& (new_state == RDS_STATE_HAVE_DATA)) {
|
||||
fm_update_rds_sync_status(radio, FALSE); /* unsynced */
|
||||
} else if ((old_state != RDS_STATE_FULL_SYNC)
|
||||
&& (new_state == RDS_STATE_FULL_SYNC)) {
|
||||
fm_update_rds_sync_status(radio, TRUE); /* synced */
|
||||
}
|
||||
}
|
||||
|
||||
void fm_rds_update_error_status(struct s610_radio *radio, u16 errors)
|
||||
{
|
||||
if (errors == 0) {
|
||||
radio->low->fm_rds_state.error_bits = 0;
|
||||
radio->low->fm_rds_state.error_blks = 0;
|
||||
} else {
|
||||
radio->low->fm_rds_state.error_bits += errors;
|
||||
radio->low->fm_rds_state.error_blks++;
|
||||
}
|
||||
|
||||
if (radio->low->fm_rds_state.error_blks
|
||||
>= radio->low->fm_state.rds_unsync_blk_cnt) {
|
||||
if (radio->low->fm_rds_state.error_bits
|
||||
>= radio->low->fm_state.rds_unsync_bit_cnt) {
|
||||
/* sync-loss */
|
||||
fm_rds_change_state(radio, RDS_STATE_HAVE_DATA);
|
||||
}
|
||||
radio->low->fm_rds_state.error_bits = 0;
|
||||
radio->low->fm_rds_state.error_blks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static fm_host_rds_errors_enum fm_rds_process_block(
|
||||
struct s610_radio *radio,
|
||||
u16 data, fm_rds_block_type_enum block_type,
|
||||
u16 err_count)
|
||||
{
|
||||
fm_host_rds_errors_enum error_type;
|
||||
|
||||
if (err_count == 0) {
|
||||
error_type = HOST_RDS_ERRS_NONE;
|
||||
} else if ((err_count <= 2)
|
||||
&& (err_count
|
||||
<= radio->low->fm_config.rds_error_limit)) {
|
||||
error_type = HOST_RDS_ERRS_2CORR;
|
||||
} else if ((err_count <= 5)
|
||||
&& (err_count
|
||||
<= radio->low->fm_config.rds_error_limit)) {
|
||||
error_type = HOST_RDS_ERRS_5CORR;
|
||||
} else {
|
||||
error_type = HOST_RDS_ERRS_UNCORR;
|
||||
}
|
||||
|
||||
/* Write the data into the buffer */
|
||||
if ((block_type != RDS_BLKTYPE_E)
|
||||
|| (radio->low->fm_state.save_eblks)) {
|
||||
fm_rds_write_data(radio, data, block_type, error_type);
|
||||
}
|
||||
|
||||
return error_type;
|
||||
}
|
||||
|
||||
void fm_process_rds_data(struct s610_radio *radio)
|
||||
{
|
||||
u32 fifo_data;
|
||||
u16 i;
|
||||
u16 avail_blocks;
|
||||
u16 data;
|
||||
u8 status;
|
||||
u16 err_count;
|
||||
fm_rds_block_type_enum block_type;
|
||||
|
||||
if (!radio->low->fm_state.rds_rx_enabled)
|
||||
return;
|
||||
|
||||
avail_blocks = (fmspeedy_get_reg_int(0xFFF2BF) + 1) / 4;
|
||||
|
||||
for (i = 0; i < avail_blocks; i++) {
|
||||
/* Fetch the RDS word data. */
|
||||
fifo_data = fmspeedy_get_reg_int(0xFFF3C0);
|
||||
|
||||
data = (u16)((fifo_data >> 16) & 0xFFFF);
|
||||
status = (u8)((fifo_data >> 8) & 0xFF);
|
||||
|
||||
block_type =
|
||||
(fm_rds_block_type_enum) ((status & RDS_BLK_TYPE_MASK)
|
||||
>> RDS_BLK_TYPE_SHIFT);
|
||||
err_count = (status & RDS_ERR_CNT_MASK);
|
||||
|
||||
switch (radio->low->fm_rds_state.current_state) {
|
||||
case RDS_STATE_INIT:
|
||||
fm_rds_change_state(radio, RDS_STATE_HAVE_DATA);
|
||||
break;
|
||||
case RDS_STATE_HAVE_DATA:
|
||||
if ((block_type == RDS_BLKTYPE_A)
|
||||
&& (err_count == 0)) {
|
||||
/* Move to full sync */
|
||||
fm_rds_change_state(radio,
|
||||
RDS_STATE_FULL_SYNC);
|
||||
fm_rds_process_block(radio,
|
||||
data, block_type, err_count);
|
||||
}
|
||||
break;
|
||||
case RDS_STATE_PRE_SYNC:
|
||||
break;
|
||||
case RDS_STATE_FULL_SYNC:
|
||||
if (fm_rds_process_block(radio,
|
||||
data, block_type, err_count)
|
||||
== HOST_RDS_ERRS_UNCORR) {
|
||||
fm_rds_update_error_status(radio,
|
||||
radio->low->fm_state.rds_unsync_uncorr_weight);
|
||||
} else {
|
||||
fm_rds_update_error_status(radio, err_count);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue