diff options
Diffstat (limited to 'firmware/target/hosted/android')
| -rw-r--r-- | firmware/target/hosted/android/dx50/adc-target.h | 0 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/backlight-dx50.c | 76 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/backlight-target.h | 31 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/button-dx50.c | 316 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/button-target.h | 72 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/lcd-dx50.c | 120 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/lcd-target.h | 29 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/pcm-dx50.c | 364 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/powermgmt-dx50.c | 97 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/tinyalsa/asound.h | 821 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/tinyalsa/asoundlib.h | 257 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/tinyalsa/mixer.c | 497 | ||||
| -rw-r--r-- | firmware/target/hosted/android/dx50/tinyalsa/pcm.c | 973 | ||||
| -rw-r--r-- | firmware/target/hosted/android/system-android.c | 54 |
14 files changed, 2 insertions, 3705 deletions
diff --git a/firmware/target/hosted/android/dx50/adc-target.h b/firmware/target/hosted/android/dx50/adc-target.h deleted file mode 100644 index e69de29..0000000 --- a/firmware/target/hosted/android/dx50/adc-target.h +++ /dev/null diff --git a/firmware/target/hosted/android/dx50/backlight-dx50.c b/firmware/target/hosted/android/dx50/backlight-dx50.c deleted file mode 100644 index 8eb4c58..0000000 --- a/firmware/target/hosted/android/dx50/backlight-dx50.c +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * Copyright (C) 2011 by Lorenzo Miori - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "config.h" -#include "system.h" -#include "backlight.h" -#include "backlight-target.h" -#include "lcd.h" -#include "lcd-target.h" -#include <fcntl.h> -#include <stdio.h> -#include "unistd.h" - -bool backlight_hw_init(void) -{ - /* We have nothing to do */ - return true; -} - -void backlight_hw_on(void) -{ - FILE *f = fopen("/sys/power/state", "w"); - fputs("on", f); - fclose(f); - lcd_enable(true); -} - -void backlight_hw_off(void) -{ - FILE * f; - - /* deny the player to sleep deep */ - f = fopen("/sys/power/wake_lock", "w"); - fputs("player", f); - fclose(f); - - /* deny the player to mute */ - f = fopen("/sys/class/codec/wm8740_mute", "w"); - fputc(0, f); - fclose(f); - - /* turn off backlight */ - f = fopen("/sys/power/state", "w"); - fputs("mem", f); - fclose(f); - -} - -void backlight_hw_brightness(int brightness) -{ - /* Just another check... */ - if (brightness > MAX_BRIGHTNESS_SETTING) - brightness = MAX_BRIGHTNESS_SETTING; - if (brightness < MIN_BRIGHTNESS_SETTING) - brightness = MIN_BRIGHTNESS_SETTING; - - FILE *f = fopen("/sys/devices/platform/rk29_backlight/backlight/rk28_bl/brightness", "w"); - fprintf(f, "%d", brightness); - fclose(f); -} diff --git a/firmware/target/hosted/android/dx50/backlight-target.h b/firmware/target/hosted/android/dx50/backlight-target.h deleted file mode 100644 index 0dc7ce3..0000000 --- a/firmware/target/hosted/android/dx50/backlight-target.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2008 by Maurus Cuelenaere - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#ifndef BACKLIGHT_TARGET_H -#define BACKLIGHT_TARGET_H - -#include <stdbool.h> - -bool backlight_hw_init(void); -void backlight_hw_on(void); -void backlight_hw_off(void); -void backlight_hw_brightness(int brightness); - -#endif /* BACKLIGHT_TARGET_H */ diff --git a/firmware/target/hosted/android/dx50/button-dx50.c b/firmware/target/hosted/android/dx50/button-dx50.c deleted file mode 100644 index 250b448..0000000 --- a/firmware/target/hosted/android/dx50/button-dx50.c +++ /dev/null @@ -1,316 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (c) 2010 Thomas Martitz - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - - -#include <stdbool.h> -#include "button.h" -#include "buttonmap.h" -#include "config.h" -#include "kernel.h" -#include "system.h" -#include "touchscreen.h" -#include "powermgmt.h" -#include "backlight.h" - -#include <linux/input.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <dirent.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/inotify.h> -#include <sys/limits.h> -#include <sys/poll.h> -#include <errno.h> - - -static struct pollfd *ufds; -static char **device_names; -static int nfds; - -enum { - PRINT_DEVICE_ERRORS = 1U << 0, - PRINT_DEVICE = 1U << 1, - PRINT_DEVICE_NAME = 1U << 2, - PRINT_DEVICE_INFO = 1U << 3, - PRINT_VERSION = 1U << 4, - PRINT_POSSIBLE_EVENTS = 1U << 5, - PRINT_INPUT_PROPS = 1U << 6, - PRINT_HID_DESCRIPTOR = 1U << 7, - - PRINT_ALL_INFO = (1U << 8) - 1, - - PRINT_LABELS = 1U << 16, -}; - -static int last_y, last_x; -static int last_btns; - -static enum { - STATE_UNKNOWN, - STATE_UP, - STATE_DOWN -} last_touch_state = STATE_UNKNOWN; - - -static int open_device(const char *device, int print_flags) -{ - int fd; - struct pollfd *new_ufds; - char **new_device_names; - - fd = open(device, O_RDWR); - if(fd < 0) { - if(print_flags & PRINT_DEVICE_ERRORS) - fprintf(stderr, "could not open %s, %s\n", device, strerror(errno)); - return -1; - } - - new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1)); - if(new_ufds == NULL) { - fprintf(stderr, "out of memory\n"); - close(fd); - return -1; - } - ufds = new_ufds; - new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1)); - if(new_device_names == NULL) { - fprintf(stderr, "out of memory\n"); - close(fd); - return -1; - } - device_names = new_device_names; - - ufds[nfds].fd = fd; - ufds[nfds].events = POLLIN; - device_names[nfds] = strdup(device); - nfds++; - - return 0; -} - - - -static int scan_dir(const char *dirname, int print_flags) -{ - char devname[PATH_MAX]; - char *filename; - DIR *dir; - struct dirent *de; - dir = opendir(dirname); - if(dir == NULL) - return -1; - strcpy(devname, dirname); - filename = devname + strlen(devname); - *filename++ = '/'; - while((de = readdir(dir))) { - if(de->d_name[0] == '.' && - (de->d_name[1] == '\0' || - (de->d_name[1] == '.' && de->d_name[2] == '\0'))) - continue; - strcpy(filename, de->d_name); - open_device(devname, print_flags); - } - closedir(dir); - return 0; -} - -bool _hold; - -bool button_hold() -{ - FILE *f = fopen("/sys/class/axppower/holdkey", "r"); - char x; - fscanf(f, "%c", &x); - fclose(f); - _hold = !(x&STATE_UNLOCKED); - return _hold; -} - - -void button_init_device(void) -{ - int res; - int print_flags = 0; - const char *device = NULL; - const char *device_path = "/dev/input"; - - nfds = 1; - ufds = calloc(1, sizeof(ufds[0])); - ufds[0].fd = inotify_init(); - ufds[0].events = POLLIN; - if(device) { - res = open_device(device, print_flags); - if(res < 0) { - // return 1; - } - } else { - res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE); - if(res < 0) { - fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno)); - // return 1; - } - res = scan_dir(device_path, print_flags); - if(res < 0) { - fprintf(stderr, "scan dir failed for %s\n", device_path); - // return 1; - } - } - - button_hold(); //store state - - set_rockbox_ready(); -} - -void touchscreen_enable_device(bool en) -{ - (void)en; /* FIXME: do something smart */ -} - - -int keycode_to_button(int keyboard_key) -{ - switch(keyboard_key){ - case KEYCODE_PWR: - return BUTTON_POWER; - - case KEYCODE_PWR_LONG: - return BUTTON_POWER_LONG; - - case KEYCODE_VOLPLUS: - return BUTTON_VOL_UP; - - case KEYCODE_VOLMINUS: - return BUTTON_VOL_DOWN; - - case KEYCODE_PREV: - return BUTTON_LEFT; - - case KEYCODE_NEXT: - return BUTTON_RIGHT; - - case KEYCODE_PLAY: - return BUTTON_PLAY; - - case KEYCODE_HOLD: - button_hold(); /* store state */ - backlight_hold_changed(_hold); - return BUTTON_NONE; - - default: - return BUTTON_NONE; - } -} - - -int button_read_device(int *data) -{ - int i; - int res; - struct input_event event; - int read_more; - unsigned button = 0; - - if(last_btns & BUTTON_POWER_LONG) - { - return last_btns; /* simulate repeat */ - } - - do { - read_more = 0; - poll(ufds, nfds, 10); - for(i = 1; i < nfds; i++) { - if(ufds[i].revents & POLLIN) { - res = read(ufds[i].fd, &event, sizeof(event)); - if(res < (int)sizeof(event)) { - fprintf(stderr, "could not get event\n"); - } - - switch(event.type) - { - case 1: /* HW-Button */ - button = keycode_to_button(event.code); - if (_hold) /* we have to wait for keycode_to_button() first to maybe clear hold state */ - break; - if (button == BUTTON_NONE) - { - last_btns = button; - break; - } -/* workaround for a wrong feedback, only present with DX90 */ -#if defined(DX90) - if (button == BUTTON_RIGHT && (last_btns & BUTTON_LEFT == BUTTON_LEFT) && !event.value) - { - button = BUTTON_LEFT; - } -#endif - if (event.value) - last_btns |= button; - else - last_btns &= (~button); - - break; - - case 3: /* Touchscreen */ - if(_hold) - break; - - switch(event.code) - { - case 53: /* x -> next will be y */ - last_x = event.value; - read_more = 1; - break; - case 54: /* y */ - last_y = event.value; - break; - case 57: /* press -> next will be x */ - if(event.value==1) - { - last_touch_state = STATE_DOWN; - read_more = 1; - } - else - last_touch_state = STATE_UP; - break; - } - break; - } - } - } - } while(read_more); - - - /* Get grid button/coordinates based on the current touchscreen mode - * - * Caveat: the caller seemingly depends on *data always being filled with - * the last known touchscreen position, so always call - * touchscreen_to_pixels() */ - int touch = touchscreen_to_pixels(last_x, last_y, data); - - if (last_touch_state == STATE_DOWN) - return last_btns | touch; - - return last_btns; -} - diff --git a/firmware/target/hosted/android/dx50/button-target.h b/firmware/target/hosted/android/dx50/button-target.h deleted file mode 100644 index adc9cf6..0000000 --- a/firmware/target/hosted/android/dx50/button-target.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2007 by Rob Purchase - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version.r - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef _BUTTON_TARGET_H_ -#define _BUTTON_TARGET_H_ - -#include <stdbool.h> - -#define HAS_BUTTON_HOLD - -/* Main unit's buttons */ -#define BUTTON_LEFT 0x00000001 -#define BUTTON_RIGHT 0x00000002 -#define BUTTON_PLAY 0x00000004 -#define BUTTON_POWER 0x00000008 -#define BUTTON_VOL_UP 0x00000010 -#define BUTTON_VOL_DOWN 0x00000020 -#define BUTTON_POWER_LONG 0x00000040 - -#define BUTTON_MAIN (BUTTON_LEFT|BUTTON_VOL_UP|BUTTON_VOL_DOWN\ - |BUTTON_RIGHT|BUTTON_PLAY|BUTTON_POWER|BUTTON_POWER_LONG) - -#define KEYCODE_LINEOUT 113 -#define KEYCODE_SPDIF 114 -#define KEYCODE_HOLD 115 -#define KEYCODE_PWR 116 -#define KEYCODE_PWR_LONG 117 -#define KEYCODE_SD 143 -#define KEYCODE_VOLPLUS 158 -#define KEYCODE_VOLMINUS 159 -#define KEYCODE_PREV 160 -#define KEYCODE_NEXT 162 -#define KEYCODE_PLAY 161 -#define STATE_UNLOCKED 16 -#define STATE_SPDIF_UNPLUGGED 32 -#define STATE_LINEOUT_UNPLUGGED 64 - -/* Touch Screen Area Buttons */ -#define BUTTON_TOPLEFT 0x00001000 -#define BUTTON_TOPMIDDLE 0x00002000 -#define BUTTON_TOPRIGHT 0x00004000 -#define BUTTON_MIDLEFT 0x00008000 -#define BUTTON_CENTER 0x00010000 -#define BUTTON_MIDRIGHT 0x00020000 -#define BUTTON_BOTTOMLEFT 0x00040000 -#define BUTTON_BOTTOMMIDDLE 0x00080000 -#define BUTTON_BOTTOMRIGHT 0x00100000 - - -/* Software power-off */ -#define POWEROFF_BUTTON BUTTON_POWER_LONG -#define POWEROFF_COUNT 0 - -#endif /* _BUTTON_TARGET_H_ */ diff --git a/firmware/target/hosted/android/dx50/lcd-dx50.c b/firmware/target/hosted/android/dx50/lcd-dx50.c deleted file mode 100644 index 4d78baa..0000000 --- a/firmware/target/hosted/android/dx50/lcd-dx50.c +++ /dev/null @@ -1,120 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id: lcd-bitmap.c 29248 2011-02-08 20:05:25Z thomasjfox $ - * - * Copyright (C) 2011 Lorenzo Miori, Thomas Martitz - * Copyright (C) 2013 Lorenzo Miori - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include <stdlib.h> -#include <unistd.h> -#include <stdio.h> -#include <linux/fb.h> -#include <sys/mman.h> -#include <sys/ioctl.h> -#include "config.h" -#include "file.h" -#include "debug.h" -#include "system.h" -#include "screendump.h" -#include "lcd.h" -#include "lcd-target.h" - -static int dev_fd = 0; -fb_data *dev_fb = 0; - -#ifdef HAVE_LCD_SHUTDOWN -void lcd_shutdown(void) -{ - printf("FB closed."); - munmap(dev_fb, FRAMEBUFFER_SIZE); - close(dev_fd); -} -#endif - -void lcd_init_device(void) -{ - size_t screensize; - struct fb_var_screeninfo vinfo; - struct fb_fix_screeninfo finfo; - - /* Open the framebuffer device */ - dev_fd = open("/dev/graphics/fb0", O_RDWR); - if (dev_fd == -1) { - perror("Error: cannot open framebuffer device"); - exit(1); - } - - /* Get the fixed properties */ - if (ioctl(dev_fd, FBIOGET_FSCREENINFO, &finfo) == -1) { - perror("Error reading fixed information"); - exit(2); - } - - - /* Now we get the settable settings, and we set 16 bit bpp */ - if (ioctl(dev_fd, FBIOGET_VSCREENINFO, &vinfo) == -1) { - perror("Error reading variable information"); - exit(3); - } - /* framebuffer does not fit the screen, a bug of iBassos Firmware, not rockbox. - cannot be solved with parameters */ - vinfo.bits_per_pixel = LCD_DEPTH; - vinfo.xres = vinfo.xres_virtual = vinfo.width = LCD_WIDTH; - vinfo.yres = vinfo.yres_virtual = vinfo.height = LCD_HEIGHT; - - if (ioctl(dev_fd, FBIOPUT_VSCREENINFO, &vinfo)) { - perror("fbset(ioctl)"); - exit(4); - } - - /* Figure out the size of the screen in bytes */ - screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; - if (screensize != FRAMEBUFFER_SIZE) { - exit(4); - perror("Display and framebuffer mismatch!\n"); - } - - /* Map the device to memory */ - dev_fb = mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0); - if ((int)dev_fb == -1) { - perror("Error: failed to map framebuffer device to memory"); - exit(4); - } - - /* Be sure to turn on display at startup */ - ioctl(dev_fd, FBIOBLANK, VESA_NO_BLANKING); -#ifdef HAVE_LCD_ENABLE - lcd_set_active(true); -#endif -} - -#ifdef HAVE_LCD_ENABLE -void lcd_enable(bool enable) - { - if (lcd_active() == enable) - return; - - lcd_set_active(enable); - - /* Turn on or off the display using Linux interface */ - ioctl(dev_fd, FBIOBLANK, enable ? VESA_NO_BLANKING : VESA_POWERDOWN); - - if (enable) - send_event(LCD_EVENT_ACTIVATION, NULL); -} -#endif diff --git a/firmware/target/hosted/android/dx50/lcd-target.h b/firmware/target/hosted/android/dx50/lcd-target.h deleted file mode 100644 index 900350e..0000000 --- a/firmware/target/hosted/android/dx50/lcd-target.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef __LCD_TARGET_H__ -#define __LCD_TARGET_H__ - -extern fb_data *dev_fb; -#define LCD_FRAMEBUF_ADDR(col, row) (dev_fb + row*LCD_WIDTH + col) -#ifdef HAVE_LCD_ENABLE -extern void lcd_set_active(bool active); -extern void lcd_enable(bool enable); -#endif -#endif diff --git a/firmware/target/hosted/android/dx50/pcm-dx50.c b/firmware/target/hosted/android/dx50/pcm-dx50.c deleted file mode 100644 index e769587..0000000 --- a/firmware/target/hosted/android/dx50/pcm-dx50.c +++ /dev/null @@ -1,364 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Thomas Martitz - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - - -/* - * Based, but heavily modified, on the example given at - * http://www.alsa-project.org/alsa-doc/alsa-lib/_2test_2pcm_8c-example.html - * - * This driver uses the so-called unsafe async callback method and hardcoded device - * names. It fails when the audio device is busy by other apps. - * - * To make the async callback safer, an alternative stack is installed, since - * it's run from a signal hanlder (which otherwise uses the user stack). If - * tick tasks are run from a signal handler too, please install - * an alternative stack for it too. - * - * TODO: Rewrite this to do it properly with multithreading - * - * Alternatively, a version using polling in a tick task is provided. While - * supposedly safer, it appears to use more CPU (however I didn't measure it - * accurately, only looked at htop). At least, in this mode the "default" - * device works which doesnt break with other apps running. - */ - - -#include "autoconf.h" - -#include <stdlib.h> -#include <stdbool.h> -#include <stdio.h> -#include <errno.h> -#include "tinyalsa/asoundlib.h" -#include "tinyalsa/asound.h" -#include "system.h" -#include "debug.h" -#include "kernel.h" - -#include "pcm.h" -#include "pcm-internal.h" -#include "pcm_mixer.h" -#include "pcm_sampr.h" -#include "audiohw.h" - -#include <pthread.h> -#include <signal.h> - -static const snd_pcm_format_t format = PCM_FORMAT_S16_LE; /* sample format */ -static const int channels = 2; /* count of channels */ -static unsigned int rate = 44100; /* stream rate */ - -typedef struct pcm snd_pcm_t; -static snd_pcm_t *handle; -struct pcm_config config; - -static snd_pcm_sframes_t period_size = 512; /* if set to >= 1024, all timers become even slower */ -static char *frames; - -static const void *pcm_data = 0; -static size_t pcm_size = 0; - -static int recursion; - -static int set_hwparams(snd_pcm_t *handle) -{ - int err; - if (!frames) - frames = malloc(pcm_frames_to_bytes(handle, pcm_get_buffer_size(handle))); - err = 0; /* success */ - return err; -} - - -/* copy pcm samples to a spare buffer, suitable for snd_pcm_writei() */ -static bool fill_frames(void) -{ - size_t copy_n, frames_left = period_size; - bool new_buffer = false; - - while (frames_left > 0) - { - if (!pcm_size) - { - new_buffer = true; - if (!pcm_play_dma_complete_callback(PCM_DMAST_OK, &pcm_data, - &pcm_size)) - { - return false; - } - } - copy_n = MIN((size_t)pcm_size, pcm_frames_to_bytes(handle, frames_left)); - memcpy(&frames[pcm_frames_to_bytes(handle, period_size-frames_left)], pcm_data, copy_n); - - pcm_data += copy_n; - pcm_size -= copy_n; - frames_left -= pcm_bytes_to_frames(handle, copy_n); - - if (new_buffer) - { - new_buffer = false; - pcm_play_dma_status_callback(PCM_DMAST_STARTED); - } - } - return true; -} - - -static void pcm_tick(void) -{ - if (fill_frames()) - { - if (pcm_write(handle, frames, pcm_frames_to_bytes(handle, period_size))) { - printf("Error playing sample\n"); - return;//break; - } - - } - else - { - DEBUGF("%s: No Data.\n", __func__); - return;//break; - } -} - -static int async_rw(snd_pcm_t *handle) -{ - int err; - snd_pcm_sframes_t sample_size; - char *samples; - - /* fill buffer with silence to initiate playback without noisy click */ - sample_size = pcm_frames_to_bytes(handle, pcm_get_buffer_size(handle)); - samples = malloc(sample_size); - - memset(samples, 0, sample_size); - - err = pcm_write(handle, samples, sample_size); - free(samples); - - if (err != 0) - { - DEBUGF("Initial write error: %d\n", err); - return err; - } - if (pcm_state(handle) == PCM_STATE_PREPARED) - { - err = pcm_start(handle); - if (err < 0) - { - DEBUGF("Start error: %d\n", err); - return err; - } - } - return 0; -} - -void cleanup(void) -{ - free(frames); - frames = NULL; - pcm_close(handle); -} - -void pcm_play_dma_init(void) -{ - config.channels = channels; - config.rate = rate; - config.period_size = period_size; - config.period_count = 4; - config.format = format; - config.start_threshold = 0; - config.stop_threshold = 0; - config.silence_threshold = 0; - - - handle = pcm_open(0, 0, PCM_OUT, &config); - if (!handle || !pcm_is_ready(handle)) { - printf("Unable to open PCM device: %s\n", pcm_get_error(handle)); - return; - } - - pcm_dma_apply_settings(); - - tick_add_task(pcm_tick); - - atexit(cleanup); - return; -} - - -void pcm_play_lock(void) -{ - if (recursion++ == 0) - tick_remove_task(pcm_tick); -} - -void pcm_play_unlock(void) -{ - if (--recursion == 0) - tick_add_task(pcm_tick); -} - -static void pcm_dma_apply_settings_nolock(void) -{ - set_hwparams(handle); -} - -void pcm_dma_apply_settings(void) -{ - pcm_play_lock(); - pcm_dma_apply_settings_nolock(); - pcm_play_unlock(); -} - - -void pcm_play_dma_pause(bool pause) -{ - (void)pause; -} - - -void pcm_play_dma_stop(void) -{ - pcm_stop(handle); -} - -void pcm_play_dma_start(const void *addr, size_t size) -{ -#if defined(DX50) || defined(DX90) - /* headphone output relay: if this is done at startup already, a loud click is audible on headphones. Here, some time later, - the output caps are charged a bit and the click is much softer */ - system("/system/bin/muteopen"); -#endif - pcm_dma_apply_settings_nolock(); - - pcm_data = addr; - pcm_size = size; - - while (1) - { - snd_pcm_state_t state = pcm_state(handle); - switch (state) - { - case PCM_STATE_RUNNING: - return; - case PCM_STATE_XRUN: - { - printf("No handler for STATE_XRUN!\n"); - continue; - } - case PCM_STATE_PREPARED: - { /* prepared state, we need to fill the buffer with silence before - * starting */ - int err = async_rw(handle); - if (err < 0) - printf("Start error: %d\n", err); - return; - } - case PCM_STATE_PAUSED: - { /* paused, simply resume */ - pcm_play_dma_pause(0); - return; - } - case PCM_STATE_DRAINING: - /* run until drained */ - continue; - default: - DEBUGF("Unhandled state: %d\n", state); - return; - } - } -} - -size_t pcm_get_bytes_waiting(void) -{ - return pcm_size; -} - -const void * pcm_play_dma_get_peak_buffer(int *count) -{ - uintptr_t addr = (uintptr_t)pcm_data; - *count = pcm_size / 4; - return (void *)((addr + 3) & ~3); -} - -void pcm_play_dma_postinit(void) -{ - return; -} - -void pcm_set_mixer_volume(int volume) -{ -#if defined(DX50) || defined(DX90) - /* -990 to 0 -> 0 to 255 */ - int val = (volume+990)*255/990; -#if defined(DX50) - FILE *f = fopen("/dev/codec_volume", "w"); -#else /* DX90 */ - FILE *f = fopen("/sys/class/codec/es9018_volume", "w"); -#endif /* DX50 */ - fprintf(f, "%d", val); - fclose(f); -#else - (void)volume; -#endif /* DX50 || DX90 */ -} - -#ifdef HAVE_RECORDING -void pcm_rec_lock(void) -{ -} - -void pcm_rec_unlock(void) -{ -} - -void pcm_rec_dma_init(void) -{ -} - -void pcm_rec_dma_close(void) -{ -} - -void pcm_rec_dma_start(void *start, size_t size) -{ - (void)start; - (void)size; -} - -void pcm_rec_dma_stop(void) -{ -} - -const void * pcm_rec_dma_get_peak_buffer(void) -{ - return NULL; -} - -void audiohw_set_recvol(int left, int right, int type) -{ - (void)left; - (void)right; - (void)type; -} - -#endif /* HAVE_RECORDING */ diff --git a/firmware/target/hosted/android/dx50/powermgmt-dx50.c b/firmware/target/hosted/android/dx50/powermgmt-dx50.c deleted file mode 100644 index 713e8a9..0000000 --- a/firmware/target/hosted/android/dx50/powermgmt-dx50.c +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 by Thomas Martitz - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include "config.h" -#include "power.h" -#include "powermgmt.h" - - -unsigned int power_input_status(void) -{ - int val; - FILE *f = fopen("/sys/class/power_supply/ac/present", "r"); - fscanf(f, "%d", &val); - fclose(f); - return val?POWER_INPUT_MAIN_CHARGER:POWER_INPUT_NONE; -} - - -/* Returns true, if battery is charging, false else. */ -bool charging_state( void ) -{ - /* Full, Charging, Discharging */ - char state[9]; - - /* true if charging. */ - bool charging = false; - - FILE *f = fopen( "/sys/class/power_supply/battery/status", "r" ); - if( f != NULL ) - { - if( fgets( state, 9, f ) != NULL ) - { - charging = ( strcmp( state, "Charging" ) == 0 ); - } - } - fclose( f ); - - return charging; -} - - -/* Values for stock PISEN battery. TODO: Needs optimization */ -const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = -{ - 3380 -}; - -const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = -{ - 3100 -}; - -/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ -const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = -{ - { 3370, 3650, 3700, 3740, 3780, 3820, 3870, 3930, 4000, 4090, 4190 } -}; - -/* Voltages (millivolt) of 0%, 10%, ... 100% when charging is enabled. */ -const unsigned short percent_to_volt_charge[11] = -{ - 3370, 3650, 3700, 3740, 3780, 3820, 3870, 3930, 4000, 4090, 4190 -}; - - -/* Returns battery voltage from android measurement [millivolts] */ -int _battery_voltage(void) -{ - int val; - FILE *f = fopen("/sys/class/power_supply/battery/voltage_now", "r"); - fscanf(f, "%d", &val); - fclose(f); - return (val/1000); -} - - diff --git a/firmware/target/hosted/android/dx50/tinyalsa/asound.h b/firmware/target/hosted/android/dx50/tinyalsa/asound.h deleted file mode 100644 index fc1e4f6..0000000 --- a/firmware/target/hosted/android/dx50/tinyalsa/asound.h +++ /dev/null @@ -1,821 +0,0 @@ -/**************************************************************************** - **************************************************************************** - *** - *** This header was automatically generated from a Linux kernel header - *** of the same name, to make information necessary for userspace to - *** call into the kernel available to libc. It contains only constants, - *** structures, and macros generated from the original header, and thus, - *** contains no copyrightable information. - *** - **************************************************************************** - ****************************************************************************/ -#ifndef __SOUND_ASOUND_H -#define __SOUND_ASOUND_H - -#include <linux/types.h> - -#define SNDRV_PROTOCOL_VERSION(major, minor, subminor) (((major)<<16)|((minor)<<8)|(subminor)) -#define SNDRV_PROTOCOL_MAJOR(version) (((version)>>16)&0xffff) -#define SNDRV_PROTOCOL_MINOR(version) (((version)>>8)&0xff) -#define SNDRV_PROTOCOL_MICRO(version) ((version)&0xff) -#define SNDRV_PROTOCOL_INCOMPATIBLE(kversion, uversion) (SNDRV_PROTOCOL_MAJOR(kversion) != SNDRV_PROTOCOL_MAJOR(uversion) || (SNDRV_PROTOCOL_MAJOR(kversion) == SNDRV_PROTOCOL_MAJOR(uversion) && SNDRV_PROTOCOL_MINOR(kversion) != SNDRV_PROTOCOL_MINOR(uversion))) - -struct snd_aes_iec958 { - unsigned char status[24]; - unsigned char subcode[147]; - unsigned char pad; - unsigned char dig_subframe[4]; -}; - -#define SNDRV_HWDEP_VERSION SNDRV_PROTOCOL_VERSION(1, 0, 1) - -enum { - SNDRV_HWDEP_IFACE_OPL2 = 0, - SNDRV_HWDEP_IFACE_OPL3, - SNDRV_HWDEP_IFACE_OPL4, - SNDRV_HWDEP_IFACE_SB16CSP, - SNDRV_HWDEP_IFACE_EMU10K1, - SNDRV_HWDEP_IFACE_YSS225, - SNDRV_HWDEP_IFACE_ICS2115, - SNDRV_HWDEP_IFACE_SSCAPE, - SNDRV_HWDEP_IFACE_VX, - SNDRV_HWDEP_IFACE_MIXART, - SNDRV_HWDEP_IFACE_USX2Y, - SNDRV_HWDEP_IFACE_EMUX_WAVETABLE, - SNDRV_HWDEP_IFACE_BLUETOOTH, - SNDRV_HWDEP_IFACE_USX2Y_PCM, - SNDRV_HWDEP_IFACE_PCXHR, - SNDRV_HWDEP_IFACE_SB_RC, - SNDRV_HWDEP_IFACE_HDA, - SNDRV_HWDEP_IFACE_USB_STREAM, - - SNDRV_HWDEP_IFACE_LAST = SNDRV_HWDEP_IFACE_USB_STREAM -}; - -struct snd_hwdep_info { - unsigned int device; - int card; - unsigned char id[64]; - unsigned char name[80]; - int iface; - unsigned char reserved[64]; -}; - -struct snd_hwdep_dsp_status { - unsigned int version; - unsigned char id[32]; - unsigned int num_dsps; - unsigned int dsp_loaded; - unsigned int chip_ready; - unsigned char reserved[16]; -}; - -struct snd_hwdep_dsp_image { - unsigned int index; - unsigned char name[64]; - unsigned char __user *image; - size_t length; - unsigned long driver_data; -}; - -#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int) -#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct snd_hwdep_info) -#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct snd_hwdep_dsp_status) -#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct snd_hwdep_dsp_image) - -#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 10) - -typedef unsigned long snd_pcm_uframes_t; -typedef signed long snd_pcm_sframes_t; - -enum { - SNDRV_PCM_CLASS_GENERIC = 0, - SNDRV_PCM_CLASS_MULTI, - SNDRV_PCM_CLASS_MODEM, - SNDRV_PCM_CLASS_DIGITIZER, - - SNDRV_PCM_CLASS_LAST = SNDRV_PCM_CLASS_DIGITIZER, -}; - -enum { - SNDRV_PCM_SUBCLASS_GENERIC_MIX = 0, - SNDRV_PCM_SUBCLASS_MULTI_MIX, - - SNDRV_PCM_SUBCLASS_LAST = SNDRV_PCM_SUBCLASS_MULTI_MIX, -}; - -enum { - SNDRV_PCM_STREAM_PLAYBACK = 0, - SNDRV_PCM_STREAM_CAPTURE, - SNDRV_PCM_STREAM_LAST = SNDRV_PCM_STREAM_CAPTURE, -}; - -typedef int __bitwise snd_pcm_access_t; -#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ((__force snd_pcm_access_t) 0) -#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ((__force snd_pcm_access_t) 1) -#define SNDRV_PCM_ACCESS_MMAP_COMPLEX ((__force snd_pcm_access_t) 2) -#define SNDRV_PCM_ACCESS_RW_INTERLEAVED ((__force snd_pcm_access_t) 3) -#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ((__force snd_pcm_access_t) 4) -#define SNDRV_PCM_ACCESS_LAST SNDRV_PCM_ACCESS_RW_NONINTERLEAVED - -typedef int __bitwise snd_pcm_format_t; -#define SNDRV_PCM_FORMAT_S8 ((__force snd_pcm_format_t) 0) -#define SNDRV_PCM_FORMAT_U8 ((__force snd_pcm_format_t) 1) -#define SNDRV_PCM_FORMAT_S16_LE ((__force snd_pcm_format_t) 2) -#define SNDRV_PCM_FORMAT_S16_BE ((__force snd_pcm_format_t) 3) -#define SNDRV_PCM_FORMAT_U16_LE ((__force snd_pcm_format_t) 4) -#define SNDRV_PCM_FORMAT_U16_BE ((__force snd_pcm_format_t) 5) -#define SNDRV_PCM_FORMAT_S24_LE ((__force snd_pcm_format_t) 6) -#define SNDRV_PCM_FORMAT_S24_BE ((__force snd_pcm_format_t) 7) -#define SNDRV_PCM_FORMAT_U24_LE ((__force snd_pcm_format_t) 8) -#define SNDRV_PCM_FORMAT_U24_BE ((__force snd_pcm_format_t) 9) -#define SNDRV_PCM_FORMAT_S32_LE ((__force snd_pcm_format_t) 10) -#define SNDRV_PCM_FORMAT_S32_BE ((__force snd_pcm_format_t) 11) -#define SNDRV_PCM_FORMAT_U32_LE ((__force snd_pcm_format_t) 12) -#define SNDRV_PCM_FORMAT_U32_BE ((__force snd_pcm_format_t) 13) -#define SNDRV_PCM_FORMAT_FLOAT_LE ((__force snd_pcm_format_t) 14) -#define SNDRV_PCM_FORMAT_FLOAT_BE ((__force snd_pcm_format_t) 15) -#define SNDRV_PCM_FORMAT_FLOAT64_LE ((__force snd_pcm_format_t) 16) -#define SNDRV_PCM_FORMAT_FLOAT64_BE ((__force snd_pcm_format_t) 17) -#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18) -#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19) -#define SNDRV_PCM_FORMAT_MU_LAW ((__force snd_pcm_format_t) 20) -#define SNDRV_PCM_FORMAT_A_LAW ((__force snd_pcm_format_t) 21) -#define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22) -#define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23) -#define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24) -#define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31) -#define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32) -#define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33) -#define SNDRV_PCM_FORMAT_U24_3LE ((__force snd_pcm_format_t) 34) -#define SNDRV_PCM_FORMAT_U24_3BE ((__force snd_pcm_format_t) 35) -#define SNDRV_PCM_FORMAT_S20_3LE ((__force snd_pcm_format_t) 36) -#define SNDRV_PCM_FORMAT_S20_3BE ((__force snd_pcm_format_t) 37) -#define SNDRV_PCM_FORMAT_U20_3LE ((__force snd_pcm_format_t) 38) -#define SNDRV_PCM_FORMAT_U20_3BE ((__force snd_pcm_format_t) 39) -#define SNDRV_PCM_FORMAT_S18_3LE ((__force snd_pcm_format_t) 40) -#define SNDRV_PCM_FORMAT_S18_3BE ((__force snd_pcm_format_t) 41) -#define SNDRV_PCM_FORMAT_U18_3LE ((__force snd_pcm_format_t) 42) -#define SNDRV_PCM_FORMAT_U18_3BE ((__force snd_pcm_format_t) 43) -#define SNDRV_PCM_FORMAT_G723_24 ((__force snd_pcm_format_t) 44) -#define SNDRV_PCM_FORMAT_G723_24_1B ((__force snd_pcm_format_t) 45) -#define SNDRV_PCM_FORMAT_G723_40 ((__force snd_pcm_format_t) 46) -#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47) -#define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_G723_40_1B - -#ifdef SNDRV_LITTLE_ENDIAN -#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_LE -#define SNDRV_PCM_FORMAT_U16 SNDRV_PCM_FORMAT_U16_LE -#define SNDRV_PCM_FORMAT_S24 SNDRV_PCM_FORMAT_S24_LE -#define SNDRV_PCM_FORMAT_U24 SNDRV_PCM_FORMAT_U24_LE -#define SNDRV_PCM_FORMAT_S32 SNDRV_PCM_FORMAT_S32_LE -#define SNDRV_PCM_FORMAT_U32 SNDRV_PCM_FORMAT_U32_LE -#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_LE -#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_LE -#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE -#endif -#ifdef SNDRV_BIG_ENDIAN -#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_BE -#define SNDRV_PCM_FORMAT_U16 SNDRV_PCM_FORMAT_U16_BE -#define SNDRV_PCM_FORMAT_S24 SNDRV_PCM_FORMAT_S24_BE -#define SNDRV_PCM_FORMAT_U24 SNDRV_PCM_FORMAT_U24_BE -#define SNDRV_PCM_FORMAT_S32 SNDRV_PCM_FORMAT_S32_BE -#define SNDRV_PCM_FORMAT_U32 SNDRV_PCM_FORMAT_U32_BE -#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_BE -#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_BE -#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE -#endif - -typedef int __bitwise snd_pcm_subformat_t; -#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0) -#define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD - -#define SNDRV_PCM_INFO_MMAP 0x00000001 -#define SNDRV_PCM_INFO_MMAP_VALID 0x00000002 -#define SNDRV_PCM_INFO_DOUBLE 0x00000004 -#define SNDRV_PCM_INFO_BATCH 0x00000010 -#define SNDRV_PCM_INFO_INTERLEAVED 0x00000100 -#define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200 -#define SNDRV_PCM_INFO_COMPLEX 0x00000400 -#define SNDRV_PCM_INFO_BLOCK_TRANSFER 0x00010000 -#define SNDRV_PCM_INFO_OVERRANGE 0x00020000 -#define SNDRV_PCM_INFO_RESUME 0x00040000 -#define SNDRV_PCM_INFO_PAUSE 0x00080000 -#define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 -#define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 -#define SNDRV_PCM_INFO_SYNC_START 0x00400000 -#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 -#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 - -typedef int __bitwise snd_pcm_state_t; -#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0) -#define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1) -#define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2) -#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3) -#define SNDRV_PCM_STATE_XRUN ((__force snd_pcm_state_t) 4) -#define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5) -#define SNDRV_PCM_STATE_PAUSED ((__force snd_pcm_state_t) 6) -#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7) -#define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8) -#define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED - -enum { - SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000, - SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000, - SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000, -}; - -union snd_pcm_sync_id { - unsigned char id[16]; - unsigned short id16[8]; - unsigned int id32[4]; -}; - -struct snd_pcm_info { - unsigned int device; - unsigned int subdevice; - int stream; - int card; - unsigned char id[64]; - unsigned char name[80]; - unsigned char subname[32]; - int dev_class; - int dev_subclass; - unsigned int subdevices_count; - unsigned int subdevices_avail; - union snd_pcm_sync_id sync; - unsigned char reserved[64]; -}; - -typedef int snd_pcm_hw_param_t; -#define SNDRV_PCM_HW_PARAM_ACCESS 0 -#define SNDRV_PCM_HW_PARAM_FORMAT 1 -#define SNDRV_PCM_HW_PARAM_SUBFORMAT 2 -#define SNDRV_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_ACCESS -#define SNDRV_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_SUBFORMAT - -#define SNDRV_PCM_HW_PARAM_SAMPLE_BITS 8 -#define SNDRV_PCM_HW_PARAM_FRAME_BITS 9 -#define SNDRV_PCM_HW_PARAM_CHANNELS 10 -#define SNDRV_PCM_HW_PARAM_RATE 11 -#define SNDRV_PCM_HW_PARAM_PERIOD_TIME 12 -#define SNDRV_PCM_HW_PARAM_PERIOD_SIZE 13 -#define SNDRV_PCM_HW_PARAM_PERIOD_BYTES 14 -#define SNDRV_PCM_HW_PARAM_PERIODS 15 -#define SNDRV_PCM_HW_PARAM_BUFFER_TIME 16 -#define SNDRV_PCM_HW_PARAM_BUFFER_SIZE 17 -#define SNDRV_PCM_HW_PARAM_BUFFER_BYTES 18 -#define SNDRV_PCM_HW_PARAM_TICK_TIME 19 -#define SNDRV_PCM_HW_PARAM_FIRST_INTERVAL SNDRV_PCM_HW_PARAM_SAMPLE_BITS -#define SNDRV_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_TICK_TIME - -#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) -#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1) -#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) - -struct snd_interval { - unsigned int min, max; - unsigned int openmin:1, - openmax:1, - integer:1, - empty:1; -}; - -#define SNDRV_MASK_MAX 256 - -struct snd_mask { - __u32 bits[(SNDRV_MASK_MAX+31)/32]; -}; - -struct snd_pcm_hw_params { - unsigned int flags; - struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; - struct snd_mask mres[5]; - struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1]; - struct snd_interval ires[9]; - unsigned int rmask; - unsigned int cmask; - unsigned int info; - unsigned int msbits; - unsigned int rate_num; - unsigned int rate_den; - snd_pcm_uframes_t fifo_size; - unsigned char reserved[64]; -}; - -enum { - SNDRV_PCM_TSTAMP_NONE = 0, - SNDRV_PCM_TSTAMP_ENABLE, - SNDRV_PCM_TSTAMP_LAST = SNDRV_PCM_TSTAMP_ENABLE, -}; - -struct snd_pcm_sw_params { - int tstamp_mode; - unsigned int period_step; - unsigned int sleep_min; - snd_pcm_uframes_t avail_min; - snd_pcm_uframes_t xfer_align; - snd_pcm_uframes_t start_threshold; - snd_pcm_uframes_t stop_threshold; - snd_pcm_uframes_t silence_threshold; - snd_pcm_uframes_t silence_size; - snd_pcm_uframes_t boundary; - unsigned char reserved[64]; -}; - -struct snd_pcm_channel_info { - unsigned int channel; - __kernel_off_t offset; - unsigned int first; - unsigned int step; -}; - -struct snd_pcm_status { - snd_pcm_state_t state; - struct timespec trigger_tstamp; - struct timespec tstamp; - snd_pcm_uframes_t appl_ptr; - snd_pcm_uframes_t hw_ptr; - snd_pcm_sframes_t delay; - snd_pcm_uframes_t avail; - snd_pcm_uframes_t avail_max; - snd_pcm_uframes_t overrange; - snd_pcm_state_t suspended_state; - unsigned char reserved[60]; -}; - -struct snd_pcm_mmap_status { - snd_pcm_state_t state; - int pad1; - snd_pcm_uframes_t hw_ptr; - struct timespec tstamp; - snd_pcm_state_t suspended_state; -}; - -struct snd_pcm_mmap_control { - snd_pcm_uframes_t appl_ptr; - snd_pcm_uframes_t avail_min; -}; - -#define SNDRV_PCM_SYNC_PTR_HWSYNC (1<<0) -#define SNDRV_PCM_SYNC_PTR_APPL (1<<1) -#define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2) - -struct snd_pcm_sync_ptr { - unsigned int flags; - union { - struct snd_pcm_mmap_status status; - unsigned char reserved[64]; - } s; - union { - struct snd_pcm_mmap_control control; - unsigned char reserved[64]; - } c; -}; - -struct snd_xferi { - snd_pcm_sframes_t result; - void __user *buf; - snd_pcm_uframes_t frames; -}; - -struct snd_xfern { - snd_pcm_sframes_t result; - void __user * __user *bufs; - snd_pcm_uframes_t frames; -}; - -enum { - SNDRV_PCM_TSTAMP_TYPE_GETTIMEOFDAY = 0, - SNDRV_PCM_TSTAMP_TYPE_MONOTONIC, - SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC, -}; - -#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int) -#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct snd_pcm_info) -#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int) -#define SNDRV_PCM_IOCTL_TTSTAMP _IOW('A', 0x03, int) -#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct snd_pcm_hw_params) -#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct snd_pcm_hw_params) -#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12) -#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct snd_pcm_sw_params) -#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct snd_pcm_status) -#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, snd_pcm_sframes_t) -#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22) -#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct snd_pcm_sync_ptr) -#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct snd_pcm_channel_info) -#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40) -#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41) -#define SNDRV_PCM_IOCTL_START _IO('A', 0x42) -#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43) -#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44) -#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int) -#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, snd_pcm_uframes_t) -#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47) -#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48) -#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, snd_pcm_uframes_t) -#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct snd_xferi) -#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct snd_xferi) -#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct snd_xfern) -#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct snd_xfern) -#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int) -#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61) - -#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 0) - -enum { - SNDRV_RAWMIDI_STREAM_OUTPUT = 0, - SNDRV_RAWMIDI_STREAM_INPUT, - SNDRV_RAWMIDI_STREAM_LAST = SNDRV_RAWMIDI_STREAM_INPUT, -}; - -#define SNDRV_RAWMIDI_INFO_OUTPUT 0x00000001 -#define SNDRV_RAWMIDI_INFO_INPUT 0x00000002 -#define SNDRV_RAWMIDI_INFO_DUPLEX 0x00000004 - -struct snd_rawmidi_info { - unsigned int device; - unsigned int subdevice; - int stream; - int card; - unsigned int flags; - unsigned char id[64]; - unsigned char name[80]; - unsigned char subname[32]; - unsigned int subdevices_count; - unsigned int subdevices_avail; - unsigned char reserved[64]; -}; - -struct snd_rawmidi_params { - int stream; - size_t buffer_size; - size_t avail_min; - unsigned int no_active_sensing: 1; - unsigned char reserved[16]; -}; - -struct snd_rawmidi_status { - int stream; - struct timespec tstamp; - size_t avail; - size_t xruns; - unsigned char reserved[16]; -}; - -#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int) -#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct snd_rawmidi_info) -#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct snd_rawmidi_params) -#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct snd_rawmidi_status) -#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int) -#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int) - -#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6) - -enum { - SNDRV_TIMER_CLASS_NONE = -1, - SNDRV_TIMER_CLASS_SLAVE = 0, - SNDRV_TIMER_CLASS_GLOBAL, - SNDRV_TIMER_CLASS_CARD, - SNDRV_TIMER_CLASS_PCM, - SNDRV_TIMER_CLASS_LAST = SNDRV_TIMER_CLASS_PCM, -}; - -enum { - SNDRV_TIMER_SCLASS_NONE = 0, - SNDRV_TIMER_SCLASS_APPLICATION, - SNDRV_TIMER_SCLASS_SEQUENCER, - SNDRV_TIMER_SCLASS_OSS_SEQUENCER, - SNDRV_TIMER_SCLASS_LAST = SNDRV_TIMER_SCLASS_OSS_SEQUENCER, -}; - -#define SNDRV_TIMER_GLOBAL_SYSTEM 0 -#define SNDRV_TIMER_GLOBAL_RTC 1 -#define SNDRV_TIMER_GLOBAL_HPET 2 -#define SNDRV_TIMER_GLOBAL_HRTIMER 3 - -#define SNDRV_TIMER_FLG_SLAVE (1<<0) - -struct snd_timer_id { - int dev_class; - int dev_sclass; - int card; - int device; - int subdevice; -}; - -struct snd_timer_ginfo { - struct snd_timer_id tid; - unsigned int flags; - int card; - unsigned char id[64]; - unsigned char name[80]; - unsigned long reserved0; - unsigned long resolution; - unsigned long resolution_min; - unsigned long resolution_max; - unsigned int clients; - unsigned char reserved[32]; -}; - -struct snd_timer_gparams { - struct snd_timer_id tid; - unsigned long period_num; - unsigned long period_den; - unsigned char reserved[32]; -}; - -struct snd_timer_gstatus { - struct snd_timer_id tid; - unsigned long resolution; - unsigned long resolution_num; - unsigned long resolution_den; - unsigned char reserved[32]; -}; - -struct snd_timer_select { - struct snd_timer_id id; - unsigned char reserved[32]; -}; - -struct snd_timer_info { - unsigned int flags; - int card; - unsigned char id[64]; - unsigned char name[80]; - unsigned long reserved0; - unsigned long resolution; - unsigned char reserved[64]; -}; - -#define SNDRV_TIMER_PSFLG_AUTO (1<<0) -#define SNDRV_TIMER_PSFLG_EXCLUSIVE (1<<1) -#define SNDRV_TIMER_PSFLG_EARLY_EVENT (1<<2) - -struct snd_timer_params { - unsigned int flags; - unsigned int ticks; - unsigned int queue_size; - unsigned int reserved0; - unsigned int filter; - unsigned char reserved[60]; -}; - -struct snd_timer_status { - struct timespec tstamp; - unsigned int resolution; - unsigned int lost; - unsigned int overrun; - unsigned int queue; - unsigned char reserved[64]; -}; - -#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int) -#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id) -#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int) -#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct snd_timer_ginfo) -#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct snd_timer_gparams) -#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct snd_timer_gstatus) -#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct snd_timer_select) -#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct snd_timer_info) -#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct snd_timer_params) -#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct snd_timer_status) - -#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0) -#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1) -#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2) -#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3) - -struct snd_timer_read { - unsigned int resolution; - unsigned int ticks; -}; - -enum { - SNDRV_TIMER_EVENT_RESOLUTION = 0, - SNDRV_TIMER_EVENT_TICK, - SNDRV_TIMER_EVENT_START, - SNDRV_TIMER_EVENT_STOP, - SNDRV_TIMER_EVENT_CONTINUE, - SNDRV_TIMER_EVENT_PAUSE, - SNDRV_TIMER_EVENT_EARLY, - SNDRV_TIMER_EVENT_SUSPEND, - SNDRV_TIMER_EVENT_RESUME, - - SNDRV_TIMER_EVENT_MSTART = SNDRV_TIMER_EVENT_START + 10, - SNDRV_TIMER_EVENT_MSTOP = SNDRV_TIMER_EVENT_STOP + 10, - SNDRV_TIMER_EVENT_MCONTINUE = SNDRV_TIMER_EVENT_CONTINUE + 10, - SNDRV_TIMER_EVENT_MPAUSE = SNDRV_TIMER_EVENT_PAUSE + 10, - SNDRV_TIMER_EVENT_MSUSPEND = SNDRV_TIMER_EVENT_SUSPEND + 10, - SNDRV_TIMER_EVENT_MRESUME = SNDRV_TIMER_EVENT_RESUME + 10, -}; - -struct snd_timer_tread { - int event; - struct timespec tstamp; - unsigned int val; -}; - -#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6) - -struct snd_ctl_card_info { - int card; - int pad; - unsigned char id[16]; - unsigned char driver[16]; - unsigned char name[32]; - unsigned char longname[80]; - unsigned char reserved_[16]; - unsigned char mixername[80]; - unsigned char components[128]; -}; - -typedef int __bitwise snd_ctl_elem_type_t; -#define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0) -#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1) -#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2) -#define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((__force snd_ctl_elem_type_t) 3) -#define SNDRV_CTL_ELEM_TYPE_BYTES ((__force snd_ctl_elem_type_t) 4) -#define SNDRV_CTL_ELEM_TYPE_IEC958 ((__force snd_ctl_elem_type_t) 5) -#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6) -#define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64 - -typedef int __bitwise snd_ctl_elem_iface_t; -#define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0) -#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1) -#define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2) -#define SNDRV_CTL_ELEM_IFACE_PCM ((__force snd_ctl_elem_iface_t) 3) -#define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((__force snd_ctl_elem_iface_t) 4) -#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5) -#define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((__force snd_ctl_elem_iface_t) 6) -#define SNDRV_CTL_ELEM_IFACE_LAST SNDRV_CTL_ELEM_IFACE_SEQUENCER - -#define SNDRV_CTL_ELEM_ACCESS_READ (1<<0) -#define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1) -#define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE) -#define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2) -#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1<<3) -#define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1<<4) -#define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE (1<<5) -#define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE (SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) -#define SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND (1<<6) -#define SNDRV_CTL_ELEM_ACCESS_INACTIVE (1<<8) -#define SNDRV_CTL_ELEM_ACCESS_LOCK (1<<9) -#define SNDRV_CTL_ELEM_ACCESS_OWNER (1<<10) -#define SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK (1<<28) -#define SNDRV_CTL_ELEM_ACCESS_USER (1<<29) - -#define SNDRV_CTL_POWER_D0 0x0000 -#define SNDRV_CTL_POWER_D1 0x0100 -#define SNDRV_CTL_POWER_D2 0x0200 -#define SNDRV_CTL_POWER_D3 0x0300 -#define SNDRV_CTL_POWER_D3hot (SNDRV_CTL_POWER_D3|0x0000) -#define SNDRV_CTL_POWER_D3cold (SNDRV_CTL_POWER_D3|0x0001) - -struct snd_ctl_elem_id { - unsigned int numid; - snd_ctl_elem_iface_t iface; - unsigned int device; - unsigned int subdevice; - unsigned char name[44]; - unsigned int index; -}; - -struct snd_ctl_elem_list { - unsigned int offset; - unsigned int space; - unsigned int used; - unsigned int count; - struct snd_ctl_elem_id __user *pids; - unsigned char reserved[50]; -}; - -struct snd_ctl_elem_info { - struct snd_ctl_elem_id id; - snd_ctl_elem_type_t type; - unsigned int access; - unsigned int count; - __kernel_pid_t owner; - union { - struct { - long min; - long max; - long step; - } integer; - struct { - long long min; - long long max; - long long step; - } integer64; - struct { - unsigned int items; - unsigned int item; - char name[64]; - } enumerated; - unsigned char reserved[128]; - } value; - union { - unsigned short d[4]; - unsigned short *d_ptr; - } dimen; - unsigned char reserved[64-4*sizeof(unsigned short)]; -}; - -struct snd_ctl_elem_value { - struct snd_ctl_elem_id id; - unsigned int indirect: 1; - union { - union { - long value[128]; - long *value_ptr; - } integer; - union { - long long value[64]; - long long *value_ptr; - } integer64; - union { - unsigned int item[128]; - unsigned int *item_ptr; - } enumerated; - union { - unsigned char data[512]; - unsigned char *data_ptr; - } bytes; - struct snd_aes_iec958 iec958; - } value; - struct timespec tstamp; - unsigned char reserved[128-sizeof(struct timespec)]; -}; - -struct snd_ctl_tlv { - unsigned int numid; - unsigned int length; - unsigned int tlv[0]; -}; - -#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int) -#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct snd_ctl_card_info) -#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct snd_ctl_elem_list) -#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct snd_ctl_elem_info) -#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct snd_ctl_elem_value) -#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct snd_ctl_elem_value) -#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct snd_ctl_elem_id) -#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct snd_ctl_elem_id) -#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int) -#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct snd_ctl_elem_info) -#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct snd_ctl_elem_info) -#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct snd_ctl_elem_id) -#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct snd_ctl_tlv) -#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct snd_ctl_tlv) -#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct snd_ctl_tlv) -#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int) -#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct snd_hwdep_info) -#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int) -#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct snd_pcm_info) -#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int) -#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int) -#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct snd_rawmidi_info) -#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int) -#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int) -#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int) - -enum sndrv_ctl_event_type { - SNDRV_CTL_EVENT_ELEM = 0, - SNDRV_CTL_EVENT_LAST = SNDRV_CTL_EVENT_ELEM, -}; - -#define SNDRV_CTL_EVENT_MASK_VALUE (1<<0) -#define SNDRV_CTL_EVENT_MASK_INFO (1<<1) -#define SNDRV_CTL_EVENT_MASK_ADD (1<<2) -#define SNDRV_CTL_EVENT_MASK_TLV (1<<3) -#define SNDRV_CTL_EVENT_MASK_REMOVE (~0U) - -struct snd_ctl_event { - int type; - union { - struct { - unsigned int mask; - struct snd_ctl_elem_id id; - } elem; - unsigned char data8[60]; - } data; -}; - -#define SNDRV_CTL_NAME_NONE "" -#define SNDRV_CTL_NAME_PLAYBACK "Playback " -#define SNDRV_CTL_NAME_CAPTURE "Capture " - -#define SNDRV_CTL_NAME_IEC958_NONE "" -#define SNDRV_CTL_NAME_IEC958_SWITCH "Switch" -#define SNDRV_CTL_NAME_IEC958_VOLUME "Volume" -#define SNDRV_CTL_NAME_IEC958_DEFAULT "Default" -#define SNDRV_CTL_NAME_IEC958_MASK "Mask" -#define SNDRV_CTL_NAME_IEC958_CON_MASK "Con Mask" -#define SNDRV_CTL_NAME_IEC958_PRO_MASK "Pro Mask" -#define SNDRV_CTL_NAME_IEC958_PCM_STREAM "PCM Stream" -#define SNDRV_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what - -#endif - diff --git a/firmware/target/hosted/android/dx50/tinyalsa/asoundlib.h b/firmware/target/hosted/android/dx50/tinyalsa/asoundlib.h deleted file mode 100644 index 6aacae4..0000000 --- a/firmware/target/hosted/android/dx50/tinyalsa/asoundlib.h +++ /dev/null @@ -1,257 +0,0 @@ -/* asoundlib.h -** -** Copyright 2011, The Android Open Source Project -** -** 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 The Android Open Source Project 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 Android Open Source Project ``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 Android Open Source Project 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. -*/ - -#ifndef ASOUNDLIB_H -#define ASOUNDLIB_H - -#include <sys/time.h> -#include <stddef.h> - -#if defined(__cplusplus) -extern "C" { -#endif - -/* - * PCM API - */ - -struct pcm; - -#define PCM_OUT 0x00000000 -#define PCM_IN 0x10000000 -#define PCM_MMAP 0x00000001 -#define PCM_NOIRQ 0x00000002 -#define PCM_NORESTART 0x00000004 /* PCM_NORESTART - when set, calls to - * pcm_write for a playback stream will not - * attempt to restart the stream in the case - * of an underflow, but will return -EPIPE - * instead. After the first -EPIPE error, the - * stream is considered to be stopped, and a - * second call to pcm_write will attempt to - * restart the stream. - */ - -/* PCM runtime states */ -#define PCM_STATE_OPEN 0 -#define PCM_STATE_SETUP 1 -#define PCM_STATE_PREPARED 2 -#define PCM_STATE_RUNNING 3 -#define PCM_STATE_XRUN 4 -#define PCM_STATE_DRAINING 5 -#define PCM_STATE_PAUSED 6 -#define PCM_STATE_SUSPENDED 7 -#define PCM_STATE_DISCONNECTED 8 - -/* Bit formats */ -enum pcm_format { - PCM_FORMAT_S16_LE = 0, - PCM_FORMAT_S32_LE, - PCM_FORMAT_S8, - PCM_FORMAT_S24_LE, - - PCM_FORMAT_MAX, -}; - -/* Configuration for a stream */ -struct pcm_config { - unsigned int channels; - unsigned int rate; - unsigned int period_size; - unsigned int period_count; - enum pcm_format format; - - /* Values to use for the ALSA start, stop and silence thresholds. Setting - * any one of these values to 0 will cause the default tinyalsa values to be - * used instead. Tinyalsa defaults are as follows. - * - * start_threshold : period_count * period_size - * stop_threshold : period_count * period_size - * silence_threshold : 0 - */ - unsigned int start_threshold; - unsigned int stop_threshold; - unsigned int silence_threshold; -}; - -/* PCM parameters */ -enum pcm_param -{ - PCM_PARAM_SAMPLE_BITS, - PCM_PARAM_FRAME_BITS, - PCM_PARAM_CHANNELS, - PCM_PARAM_RATE, - PCM_PARAM_PERIOD_TIME, - PCM_PARAM_PERIOD_SIZE, - PCM_PARAM_PERIOD_BYTES, - PCM_PARAM_PERIODS, - PCM_PARAM_BUFFER_TIME, - PCM_PARAM_BUFFER_SIZE, - PCM_PARAM_BUFFER_BYTES, - PCM_PARAM_TICK_TIME, -}; - -/* Mixer control types */ -enum mixer_ctl_type { - MIXER_CTL_TYPE_BOOL, - MIXER_CTL_TYPE_INT, - MIXER_CTL_TYPE_ENUM, - MIXER_CTL_TYPE_BYTE, - MIXER_CTL_TYPE_IEC958, - MIXER_CTL_TYPE_INT64, - MIXER_CTL_TYPE_UNKNOWN, - - MIXER_CTL_TYPE_MAX, -}; - -/* Open and close a stream */ -struct pcm *pcm_open(unsigned int card, unsigned int device, - unsigned int flags, struct pcm_config *config); -int pcm_close(struct pcm *pcm); -int pcm_is_ready(struct pcm *pcm); - -/* Obtain the parameters for a PCM */ -struct pcm_params *pcm_params_get(unsigned int card, unsigned int device, - unsigned int flags); -void pcm_params_free(struct pcm_params *pcm_params); -unsigned int pcm_params_get_min(struct pcm_params *pcm_params, - enum pcm_param param); -unsigned int pcm_params_get_max(struct pcm_params *pcm_params, - enum pcm_param param); - -/* Set and get config */ -int pcm_get_config(struct pcm *pcm, struct pcm_config *config); -int pcm_set_config(struct pcm *pcm, struct pcm_config *config); - -/* Returns a human readable reason for the last error */ -const char *pcm_get_error(struct pcm *pcm); - -/* Returns the sample size in bits for a PCM format. - * As with ALSA formats, this is the storage size for the format, whereas the - * format represents the number of significant bits. For example, - * PCM_FORMAT_S24_LE uses 32 bits of storage. - */ -unsigned int pcm_format_to_bits(enum pcm_format format); - -/* Returns the buffer size (int frames) that should be used for pcm_write. */ -unsigned int pcm_get_buffer_size(struct pcm *pcm); -unsigned int pcm_frames_to_bytes(struct pcm *pcm, unsigned int frames); -unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes); - -/* Returns the pcm latency in ms */ -unsigned int pcm_get_latency(struct pcm *pcm); - -/* Returns available frames in pcm buffer and corresponding time stamp. - * For an input stream, frames available are frames ready for the - * application to read. - * For an output stream, frames available are the number of empty frames available - * for the application to write. - */ -int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail, - struct timespec *tstamp); - -/* Write data to the fifo. - * Will start playback on the first write or on a write that - * occurs after a fifo underrun. - */ -int pcm_write(struct pcm *pcm, const void *data, unsigned int count); -int pcm_read(struct pcm *pcm, void *data, unsigned int count); - -/* - * mmap() support. - */ -int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count); -int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset, - unsigned int *frames); -int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames); - - -/* Start and stop a PCM channel that doesn't transfer data */ -int pcm_start(struct pcm *pcm); -int pcm_stop(struct pcm *pcm); - -/* Interrupt driven API */ -int pcm_wait(struct pcm *pcm, int timeout); - -int pcm_avail_update(struct pcm *pcm); - -int pcm_state(struct pcm *pcm); - - -/* - * MIXER API - */ - -struct mixer; -struct mixer_ctl; - -/* Open and close a mixer */ -struct mixer *mixer_open(unsigned int card); -void mixer_close(struct mixer *mixer); - -/* Get info about a mixer */ -const char *mixer_get_name(struct mixer *mixer); - -/* Obtain mixer controls */ -unsigned int mixer_get_num_ctls(struct mixer *mixer); -struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id); -struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name); - -/* Get info about mixer controls */ -const char *mixer_ctl_get_name(struct mixer_ctl *ctl); -enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl); -const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl); -unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl); -unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl); -const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl, - unsigned int enum_id); - -/* Some sound cards update their controls due to external events, - * such as HDMI EDID byte data changing when an HDMI cable is - * connected. This API allows the count of elements to be updated. - */ -void mixer_ctl_update(struct mixer_ctl *ctl); - -/* Set and get mixer controls */ -int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id); -int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent); - -int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id); -int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count); -int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value); -int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count); -int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string); - -/* Determe range of integer mixer controls */ -int mixer_ctl_get_range_min(struct mixer_ctl *ctl); -int mixer_ctl_get_range_max(struct mixer_ctl *ctl); - -#if defined(__cplusplus) -} /* extern "C" */ -#endif - -#endif diff --git a/firmware/target/hosted/android/dx50/tinyalsa/mixer.c b/firmware/target/hosted/android/dx50/tinyalsa/mixer.c deleted file mode 100644 index f75dec4..0000000 --- a/firmware/target/hosted/android/dx50/tinyalsa/mixer.c +++ /dev/null @@ -1,497 +0,0 @@ -/* mixer.c -** -** Copyright 2011, The Android Open Source Project -** -** 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 The Android Open Source Project 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 Android Open Source Project ``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 Android Open Source Project 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 <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> - -#include <sys/ioctl.h> - -#include <linux/ioctl.h> -#define __force -#define __bitwise -#define __user -#include <tinyalsa/asound.h> - -#include <tinyalsa/asoundlib.h> - -struct mixer_ctl { - struct mixer *mixer; - struct snd_ctl_elem_info *info; - char **ename; -}; - -struct mixer { - int fd; - struct snd_ctl_card_info card_info; - struct snd_ctl_elem_info *elem_info; - struct mixer_ctl *ctl; - unsigned int count; -}; - -void mixer_close(struct mixer *mixer) -{ - unsigned int n,m; - - if (!mixer) - return; - - if (mixer->fd >= 0) - close(mixer->fd); - - if (mixer->ctl) { - for (n = 0; n < mixer->count; n++) { - if (mixer->ctl[n].ename) { - unsigned int max = mixer->ctl[n].info->value.enumerated.items; - for (m = 0; m < max; m++) - free(mixer->ctl[n].ename[m]); - free(mixer->ctl[n].ename); - } - } - free(mixer->ctl); - } - - if (mixer->elem_info) - free(mixer->elem_info); - - free(mixer); - - /* TODO: verify frees */ -} - -struct mixer *mixer_open(unsigned int card) -{ - struct snd_ctl_elem_list elist; - struct snd_ctl_elem_info tmp; - struct snd_ctl_elem_id *eid = NULL; - struct mixer *mixer = NULL; - unsigned int n, m; - int fd; - char fn[256]; - - snprintf(fn, sizeof(fn), "/dev/snd/controlC%u", card); - fd = open(fn, O_RDWR); - if (fd < 0) - return 0; - - memset(&elist, 0, sizeof(elist)); - if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0) - goto fail; - - mixer = calloc(1, sizeof(*mixer)); - if (!mixer) - goto fail; - - mixer->ctl = calloc(elist.count, sizeof(struct mixer_ctl)); - mixer->elem_info = calloc(elist.count, sizeof(struct snd_ctl_elem_info)); - if (!mixer->ctl || !mixer->elem_info) - goto fail; - - if (ioctl(fd, SNDRV_CTL_IOCTL_CARD_INFO, &mixer->card_info) < 0) - goto fail; - - eid = calloc(elist.count, sizeof(struct snd_ctl_elem_id)); - if (!eid) - goto fail; - - mixer->count = elist.count; - mixer->fd = fd; - elist.space = mixer->count; - elist.pids = eid; - if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_LIST, &elist) < 0) - goto fail; - - for (n = 0; n < mixer->count; n++) { - struct snd_ctl_elem_info *ei = mixer->elem_info + n; - ei->id.numid = eid[n].numid; - if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, ei) < 0) - goto fail; - mixer->ctl[n].info = ei; - mixer->ctl[n].mixer = mixer; - if (ei->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) { - char **enames = calloc(ei->value.enumerated.items, sizeof(char*)); - if (!enames) - goto fail; - mixer->ctl[n].ename = enames; - for (m = 0; m < ei->value.enumerated.items; m++) { - memset(&tmp, 0, sizeof(tmp)); - tmp.id.numid = ei->id.numid; - tmp.value.enumerated.item = m; - if (ioctl(fd, SNDRV_CTL_IOCTL_ELEM_INFO, &tmp) < 0) - goto fail; - enames[m] = strdup(tmp.value.enumerated.name); - if (!enames[m]) - goto fail; - } - } - } - - free(eid); - return mixer; - -fail: - /* TODO: verify frees in failure case */ - if (eid) - free(eid); - if (mixer) - mixer_close(mixer); - else if (fd >= 0) - close(fd); - return 0; -} - -const char *mixer_get_name(struct mixer *mixer) -{ - return (const char *)mixer->card_info.name; -} - -unsigned int mixer_get_num_ctls(struct mixer *mixer) -{ - if (!mixer) - return 0; - - return mixer->count; -} - -struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id) -{ - if (mixer && (id < mixer->count)) - return mixer->ctl + id; - - return NULL; -} - -struct mixer_ctl *mixer_get_ctl_by_name(struct mixer *mixer, const char *name) -{ - unsigned int n; - - if (!mixer) - return NULL; - - for (n = 0; n < mixer->count; n++) - if (!strcmp(name, (char*) mixer->elem_info[n].id.name)) - return mixer->ctl + n; - - return NULL; -} - -void mixer_ctl_update(struct mixer_ctl *ctl) -{ - ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_INFO, ctl->info); -} - -const char *mixer_ctl_get_name(struct mixer_ctl *ctl) -{ - if (!ctl) - return NULL; - - return (const char *)ctl->info->id.name; -} - -enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl) -{ - if (!ctl) - return MIXER_CTL_TYPE_UNKNOWN; - - switch (ctl->info->type) { - case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return MIXER_CTL_TYPE_BOOL; - case SNDRV_CTL_ELEM_TYPE_INTEGER: return MIXER_CTL_TYPE_INT; - case SNDRV_CTL_ELEM_TYPE_ENUMERATED: return MIXER_CTL_TYPE_ENUM; - case SNDRV_CTL_ELEM_TYPE_BYTES: return MIXER_CTL_TYPE_BYTE; - case SNDRV_CTL_ELEM_TYPE_IEC958: return MIXER_CTL_TYPE_IEC958; - case SNDRV_CTL_ELEM_TYPE_INTEGER64: return MIXER_CTL_TYPE_INT64; - default: return MIXER_CTL_TYPE_UNKNOWN; - }; -} - -const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl) -{ - if (!ctl) - return ""; - - switch (ctl->info->type) { - case SNDRV_CTL_ELEM_TYPE_BOOLEAN: return "BOOL"; - case SNDRV_CTL_ELEM_TYPE_INTEGER: return "INT"; - case SNDRV_CTL_ELEM_TYPE_ENUMERATED: return "ENUM"; - case SNDRV_CTL_ELEM_TYPE_BYTES: return "BYTE"; - case SNDRV_CTL_ELEM_TYPE_IEC958: return "IEC958"; - case SNDRV_CTL_ELEM_TYPE_INTEGER64: return "INT64"; - default: return "Unknown"; - }; -} - -unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl) -{ - if (!ctl) - return 0; - - return ctl->info->count; -} - -static int percent_to_int(struct snd_ctl_elem_info *ei, int percent) -{ - int range; - - if (percent > 100) - percent = 100; - else if (percent < 0) - percent = 0; - - range = (ei->value.integer.max - ei->value.integer.min); - - return ei->value.integer.min + (range * percent) / 100; -} - -static int int_to_percent(struct snd_ctl_elem_info *ei, int value) -{ - int range = (ei->value.integer.max - ei->value.integer.min); - - if (range == 0) - return 0; - - return ((value - ei->value.integer.min) / range) * 100; -} - -int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id) -{ - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) - return -EINVAL; - - return int_to_percent(ctl->info, mixer_ctl_get_value(ctl, id)); -} - -int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent) -{ - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) - return -EINVAL; - - return mixer_ctl_set_value(ctl, id, percent_to_int(ctl->info, percent)); -} - -int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id) -{ - struct snd_ctl_elem_value ev; - int ret; - - if (!ctl || (id >= ctl->info->count)) - return -EINVAL; - - memset(&ev, 0, sizeof(ev)); - ev.id.numid = ctl->info->id.numid; - ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev); - if (ret < 0) - return ret; - - switch (ctl->info->type) { - case SNDRV_CTL_ELEM_TYPE_BOOLEAN: - return !!ev.value.integer.value[id]; - - case SNDRV_CTL_ELEM_TYPE_INTEGER: - return ev.value.integer.value[id]; - - case SNDRV_CTL_ELEM_TYPE_ENUMERATED: - return ev.value.enumerated.item[id]; - - case SNDRV_CTL_ELEM_TYPE_BYTES: - return ev.value.bytes.data[id]; - - default: - return -EINVAL; - } - - return 0; -} - -int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count) -{ - struct snd_ctl_elem_value ev; - int ret; - size_t size; - void *source; - - if (!ctl || (count > ctl->info->count) || !count || !array) - return -EINVAL; - - memset(&ev, 0, sizeof(ev)); - ev.id.numid = ctl->info->id.numid; - - ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev); - if (ret < 0) - return ret; - - switch (ctl->info->type) { - case SNDRV_CTL_ELEM_TYPE_BOOLEAN: - case SNDRV_CTL_ELEM_TYPE_INTEGER: - size = sizeof(ev.value.integer.value[0]); - source = ev.value.integer.value; - break; - - case SNDRV_CTL_ELEM_TYPE_BYTES: - size = sizeof(ev.value.bytes.data[0]); - source = ev.value.bytes.data; - break; - - default: - return -EINVAL; - } - - memcpy(array, source, size * count); - - return 0; -} - -int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value) -{ - struct snd_ctl_elem_value ev; - int ret; - - if (!ctl || (id >= ctl->info->count)) - return -EINVAL; - - memset(&ev, 0, sizeof(ev)); - ev.id.numid = ctl->info->id.numid; - ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev); - if (ret < 0) - return ret; - - switch (ctl->info->type) { - case SNDRV_CTL_ELEM_TYPE_BOOLEAN: - ev.value.integer.value[id] = !!value; - break; - - case SNDRV_CTL_ELEM_TYPE_INTEGER: - ev.value.integer.value[id] = value; - break; - - case SNDRV_CTL_ELEM_TYPE_ENUMERATED: - ev.value.enumerated.item[id] = value; - break; - - default: - return -EINVAL; - } - - return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev); -} - -int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count) -{ - struct snd_ctl_elem_value ev; - size_t size; - void *dest; - - if (!ctl || (count > ctl->info->count) || !count || !array) - return -EINVAL; - - memset(&ev, 0, sizeof(ev)); - ev.id.numid = ctl->info->id.numid; - - switch (ctl->info->type) { - case SNDRV_CTL_ELEM_TYPE_BOOLEAN: - case SNDRV_CTL_ELEM_TYPE_INTEGER: - size = sizeof(ev.value.integer.value[0]); - dest = ev.value.integer.value; - break; - - case SNDRV_CTL_ELEM_TYPE_BYTES: - size = sizeof(ev.value.bytes.data[0]); - dest = ev.value.bytes.data; - break; - - default: - return -EINVAL; - } - - memcpy(dest, array, size * count); - - return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev); -} - -int mixer_ctl_get_range_min(struct mixer_ctl *ctl) -{ - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) - return -EINVAL; - - return ctl->info->value.integer.min; -} - -int mixer_ctl_get_range_max(struct mixer_ctl *ctl) -{ - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) - return -EINVAL; - - return ctl->info->value.integer.max; -} - -unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl) -{ - if (!ctl) - return 0; - - return ctl->info->value.enumerated.items; -} - -const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl, - unsigned int enum_id) -{ - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) || - (enum_id >= ctl->info->value.enumerated.items)) - return NULL; - - return (const char *)ctl->ename[enum_id]; -} - -int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string) -{ - unsigned int i, num_enums; - struct snd_ctl_elem_value ev; - int ret; - - if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED)) - return -EINVAL; - - num_enums = ctl->info->value.enumerated.items; - for (i = 0; i < num_enums; i++) { - if (!strcmp(string, ctl->ename[i])) { - memset(&ev, 0, sizeof(ev)); - ev.value.enumerated.item[0] = i; - ev.id.numid = ctl->info->id.numid; - ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev); - if (ret < 0) - return ret; - return 0; - } - } - - return -EINVAL; -} - diff --git a/firmware/target/hosted/android/dx50/tinyalsa/pcm.c b/firmware/target/hosted/android/dx50/tinyalsa/pcm.c deleted file mode 100644 index bd44dce..0000000 --- a/firmware/target/hosted/android/dx50/tinyalsa/pcm.c +++ /dev/null @@ -1,973 +0,0 @@ -/* pcm.c -** -** Copyright 2011, The Android Open Source Project -** -** 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 The Android Open Source Project 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 Android Open Source Project ``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 Android Open Source Project 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 <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <stdarg.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <poll.h> - -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/time.h> -#include <limits.h> - -#include <linux/ioctl.h> -#define __force -#define __bitwise -#define __user -#include <tinyalsa/asound.h> - -#include <tinyalsa/asoundlib.h> - -#define PARAM_MAX SNDRV_PCM_HW_PARAM_LAST_INTERVAL -#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) - -static inline int param_is_mask(int p) -{ - return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) && - (p <= SNDRV_PCM_HW_PARAM_LAST_MASK); -} - -static inline int param_is_interval(int p) -{ - return (p >= SNDRV_PCM_HW_PARAM_FIRST_INTERVAL) && - (p <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL); -} - -static inline struct snd_interval *param_to_interval(struct snd_pcm_hw_params *p, int n) -{ - return &(p->intervals[n - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]); -} - -static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p, int n) -{ - return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]); -} - -static void param_set_mask(struct snd_pcm_hw_params *p, int n, unsigned int bit) -{ - if (bit >= SNDRV_MASK_MAX) - return; - if (param_is_mask(n)) { - struct snd_mask *m = param_to_mask(p, n); - m->bits[0] = 0; - m->bits[1] = 0; - m->bits[bit >> 5] |= (1 << (bit & 31)); - } -} - -static void param_set_min(struct snd_pcm_hw_params *p, int n, unsigned int val) -{ - if (param_is_interval(n)) { - struct snd_interval *i = param_to_interval(p, n); - i->min = val; - } -} - -static unsigned int param_get_min(struct snd_pcm_hw_params *p, int n) -{ - if (param_is_interval(n)) { - struct snd_interval *i = param_to_interval(p, n); - return i->min; - } - return 0; -} - -static unsigned int param_get_max(struct snd_pcm_hw_params *p, int n) -{ - if (param_is_interval(n)) { - struct snd_interval *i = param_to_interval(p, n); - return i->max; - } - return 0; -} - -static void param_set_int(struct snd_pcm_hw_params *p, int n, unsigned int val) -{ - if (param_is_interval(n)) { - struct snd_interval *i = param_to_interval(p, n); - i->min = val; - i->max = val; - i->integer = 1; - } -} - -static unsigned int param_get_int(struct snd_pcm_hw_params *p, int n) -{ - if (param_is_interval(n)) { - struct snd_interval *i = param_to_interval(p, n); - if (i->integer) - return i->max; - } - return 0; -} - -static void param_init(struct snd_pcm_hw_params *p) -{ - int n; - - memset(p, 0, sizeof(*p)); - for (n = SNDRV_PCM_HW_PARAM_FIRST_MASK; - n <= SNDRV_PCM_HW_PARAM_LAST_MASK; n++) { - struct snd_mask *m = param_to_mask(p, n); - m->bits[0] = ~0; - m->bits[1] = ~0; - } - for (n = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL; - n <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; n++) { - struct snd_interval *i = param_to_interval(p, n); - i->min = 0; - i->max = ~0; - } - p->rmask = ~0U; - p->cmask = 0; - p->info = ~0U; -} - -#define PCM_ERROR_MAX 128 - -struct pcm { - int fd; - unsigned int flags; - int running:1; - int underruns; - unsigned int buffer_size; - unsigned int boundary; - char error[PCM_ERROR_MAX]; - struct pcm_config config; - struct snd_pcm_mmap_status *mmap_status; - struct snd_pcm_mmap_control *mmap_control; - struct snd_pcm_sync_ptr *sync_ptr; - void *mmap_buffer; - unsigned int noirq_frames_per_msec; -}; - -unsigned int pcm_get_buffer_size(struct pcm *pcm) -{ - return pcm->buffer_size; -} - -const char* pcm_get_error(struct pcm *pcm) -{ - return pcm->error; -} - -static int oops(struct pcm *pcm, int e, const char *fmt, ...) -{ - va_list ap; - int sz; - - va_start(ap, fmt); - vsnprintf(pcm->error, PCM_ERROR_MAX, fmt, ap); - va_end(ap); - sz = strlen(pcm->error); - - if (errno) - snprintf(pcm->error + sz, PCM_ERROR_MAX - sz, - ": %s", strerror(e)); - return -1; -} - -static unsigned int pcm_format_to_alsa(enum pcm_format format) -{ - switch (format) { - case PCM_FORMAT_S32_LE: - return SNDRV_PCM_FORMAT_S32_LE; - case PCM_FORMAT_S8: - return SNDRV_PCM_FORMAT_S8; - case PCM_FORMAT_S24_LE: - return SNDRV_PCM_FORMAT_S24_LE; - default: - case PCM_FORMAT_S16_LE: - return SNDRV_PCM_FORMAT_S16_LE; - }; -} - -unsigned int pcm_format_to_bits(enum pcm_format format) -{ - switch (format) { - case PCM_FORMAT_S32_LE: - case PCM_FORMAT_S24_LE: - return 32; - default: - case PCM_FORMAT_S16_LE: - return 16; - }; -} - -unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes) -{ - return bytes / (pcm->config.channels * - (pcm_format_to_bits(pcm->config.format) >> 3)); -} - -unsigned int pcm_frames_to_bytes(struct pcm *pcm, unsigned int frames) -{ - return frames * pcm->config.channels * - (pcm_format_to_bits(pcm->config.format) >> 3); -} - -static int pcm_sync_ptr(struct pcm *pcm, int flags) { - if (pcm->sync_ptr) { - pcm->sync_ptr->flags = flags; - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SYNC_PTR, pcm->sync_ptr) < 0) - return -1; - } - return 0; -} - -static int pcm_hw_mmap_status(struct pcm *pcm) { - - if (pcm->sync_ptr) - return 0; - - int page_size = sysconf(_SC_PAGE_SIZE); - pcm->mmap_status = mmap(NULL, page_size, PROT_READ, MAP_FILE | MAP_SHARED, - pcm->fd, SNDRV_PCM_MMAP_OFFSET_STATUS); - if (pcm->mmap_status == MAP_FAILED) - pcm->mmap_status = NULL; - if (!pcm->mmap_status) - goto mmap_error; - - pcm->mmap_control = mmap(NULL, page_size, PROT_READ | PROT_WRITE, - MAP_FILE | MAP_SHARED, pcm->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL); - if (pcm->mmap_control == MAP_FAILED) - pcm->mmap_control = NULL; - if (!pcm->mmap_control) { - munmap(pcm->mmap_status, page_size); - pcm->mmap_status = NULL; - goto mmap_error; - } - pcm->mmap_control->avail_min = 1; - - return 0; - -mmap_error: - - pcm->sync_ptr = calloc(1, sizeof(*pcm->sync_ptr)); - if (!pcm->sync_ptr) - return -ENOMEM; - pcm->mmap_status = &pcm->sync_ptr->s.status; - pcm->mmap_control = &pcm->sync_ptr->c.control; - pcm->mmap_control->avail_min = 1; - pcm_sync_ptr(pcm, 0); - - return 0; -} - -static void pcm_hw_munmap_status(struct pcm *pcm) { - if (pcm->sync_ptr) { - free(pcm->sync_ptr); - pcm->sync_ptr = NULL; - } else { - int page_size = sysconf(_SC_PAGE_SIZE); - if (pcm->mmap_status) - munmap(pcm->mmap_status, page_size); - if (pcm->mmap_control) - munmap(pcm->mmap_control, page_size); - } - pcm->mmap_status = NULL; - pcm->mmap_control = NULL; -} - -static int pcm_areas_copy(struct pcm *pcm, unsigned int pcm_offset, - const char *src, unsigned int src_offset, - unsigned int frames) -{ - int size_bytes = pcm_frames_to_bytes(pcm, frames); - int pcm_offset_bytes = pcm_frames_to_bytes(pcm, pcm_offset); - int src_offset_bytes = pcm_frames_to_bytes(pcm, src_offset); - - /* interleaved only atm */ - memcpy((char*)pcm->mmap_buffer + pcm_offset_bytes, - src + src_offset_bytes, size_bytes); - return 0; -} - -static int pcm_mmap_write_areas(struct pcm *pcm, const char *src, - unsigned int offset, unsigned int size) -{ - void *pcm_areas; - int commit; - unsigned int pcm_offset, frames, count = 0; - - while (size > 0) { - frames = size; - pcm_mmap_begin(pcm, &pcm_areas, &pcm_offset, &frames); - pcm_areas_copy(pcm, pcm_offset, src, offset, frames); - commit = pcm_mmap_commit(pcm, pcm_offset, frames); - if (commit < 0) { - oops(pcm, commit, "failed to commit %d frames\n", frames); - return commit; - } - - offset += commit; - count += commit; - size -= commit; - } - return count; -} - -int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail, - struct timespec *tstamp) -{ - int frames; - int rc; - snd_pcm_uframes_t hw_ptr; - - if (!pcm_is_ready(pcm)) - return -1; - - rc = pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_APPL|SNDRV_PCM_SYNC_PTR_HWSYNC); - if (rc < 0) - return -1; - - if ((pcm->mmap_status->state != PCM_STATE_RUNNING) && - (pcm->mmap_status->state != PCM_STATE_DRAINING)) - return -1; - - *tstamp = pcm->mmap_status->tstamp; - if (tstamp->tv_sec == 0 && tstamp->tv_nsec == 0) - return -1; - - hw_ptr = pcm->mmap_status->hw_ptr; - if (pcm->flags & PCM_IN) - frames = hw_ptr - pcm->mmap_control->appl_ptr; - else - frames = hw_ptr + pcm->buffer_size - pcm->mmap_control->appl_ptr; - - if (frames < 0) - return -1; - - *avail = (unsigned int)frames; - - return 0; -} - -int pcm_write(struct pcm *pcm, const void *data, unsigned int count) -{ - struct snd_xferi x; - - if (pcm->flags & PCM_IN) - return -EINVAL; - - x.buf = (void*)data; - x.frames = count / (pcm->config.channels * - pcm_format_to_bits(pcm->config.format) / 8); - - for (;;) { - if (!pcm->running) { - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE)) - return oops(pcm, errno, "cannot prepare channel"); - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) - return oops(pcm, errno, "cannot write initial data"); - pcm->running = 1; - return 0; - } - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) { - pcm->running = 0; - if (errno == EPIPE) { - /* we failed to make our window -- try to restart if we are - * allowed to do so. Otherwise, simply allow the EPIPE error to - * propagate up to the app level */ - pcm->underruns++; - if (pcm->flags & PCM_NORESTART) - return -EPIPE; - continue; - } - return oops(pcm, errno, "cannot write stream data"); - } - return 0; - } -} - -int pcm_read(struct pcm *pcm, void *data, unsigned int count) -{ - struct snd_xferi x; - - if (!(pcm->flags & PCM_IN)) - return -EINVAL; - - x.buf = data; - x.frames = count / (pcm->config.channels * - pcm_format_to_bits(pcm->config.format) / 8); - - for (;;) { - if (!pcm->running) { - if (pcm_start(pcm) < 0) { - fprintf(stderr, "start error"); - return -errno; - } - } - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) { - pcm->running = 0; - if (errno == EPIPE) { - /* we failed to make our window -- try to restart */ - pcm->underruns++; - continue; - } - return oops(pcm, errno, "cannot read stream data"); - } - return 0; - } -} - -static struct pcm bad_pcm = { - .fd = -1, -}; - -struct pcm_params *pcm_params_get(unsigned int card, unsigned int device, - unsigned int flags) -{ - struct snd_pcm_hw_params *params; - char fn[256]; - int fd; - - snprintf(fn, sizeof(fn), "/dev/snd/pcmC%uD%u%c", card, device, - flags & PCM_IN ? 'c' : 'p'); - - fd = open(fn, O_RDWR); - if (fd < 0) { - fprintf(stderr, "cannot open device '%s'\n", fn); - goto err_open; - } - - params = calloc(1, sizeof(struct snd_pcm_hw_params)); - if (!params) - goto err_calloc; - - param_init(params); - if (ioctl(fd, SNDRV_PCM_IOCTL_HW_REFINE, params)) { - fprintf(stderr, "SNDRV_PCM_IOCTL_HW_REFINE error (%d)\n", errno); - goto err_hw_refine; - } - - close(fd); - - return (struct pcm_params *)params; - -err_hw_refine: - free(params); -err_calloc: - close(fd); -err_open: - return NULL; -} - -void pcm_params_free(struct pcm_params *pcm_params) -{ - struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params; - - if (params) - free(params); -} - -static int pcm_param_to_alsa(enum pcm_param param) -{ - switch (param) { - case PCM_PARAM_SAMPLE_BITS: - return SNDRV_PCM_HW_PARAM_SAMPLE_BITS; - break; - case PCM_PARAM_FRAME_BITS: - return SNDRV_PCM_HW_PARAM_FRAME_BITS; - break; - case PCM_PARAM_CHANNELS: - return SNDRV_PCM_HW_PARAM_CHANNELS; - break; - case PCM_PARAM_RATE: - return SNDRV_PCM_HW_PARAM_RATE; - break; - case PCM_PARAM_PERIOD_TIME: - return SNDRV_PCM_HW_PARAM_PERIOD_TIME; - break; - case PCM_PARAM_PERIOD_SIZE: - return SNDRV_PCM_HW_PARAM_PERIOD_SIZE; - break; - case PCM_PARAM_PERIOD_BYTES: - return SNDRV_PCM_HW_PARAM_PERIOD_BYTES; - break; - case PCM_PARAM_PERIODS: - return SNDRV_PCM_HW_PARAM_PERIODS; - break; - case PCM_PARAM_BUFFER_TIME: - return SNDRV_PCM_HW_PARAM_BUFFER_TIME; - break; - case PCM_PARAM_BUFFER_SIZE: - return SNDRV_PCM_HW_PARAM_BUFFER_SIZE; - break; - case PCM_PARAM_BUFFER_BYTES: - return SNDRV_PCM_HW_PARAM_BUFFER_BYTES; - break; - case PCM_PARAM_TICK_TIME: - return SNDRV_PCM_HW_PARAM_TICK_TIME; - break; - - default: - return -1; - } -} - -unsigned int pcm_params_get_min(struct pcm_params *pcm_params, - enum pcm_param param) -{ - struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params; - int p; - - if (!params) - return 0; - - p = pcm_param_to_alsa(param); - if (p < 0) - return 0; - - return param_get_min(params, p); -} - -unsigned int pcm_params_get_max(struct pcm_params *pcm_params, - enum pcm_param param) -{ - struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params; - int p; - - if (!params) - return 0; - - p = pcm_param_to_alsa(param); - if (p < 0) - return 0; - - return param_get_max(params, p); -} - -int pcm_close(struct pcm *pcm) -{ - if (pcm == &bad_pcm) - return 0; - - pcm_hw_munmap_status(pcm); - - if (pcm->flags & PCM_MMAP) { - pcm_stop(pcm); - munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size)); - } - - if (pcm->fd >= 0) - close(pcm->fd); - pcm->running = 0; - pcm->buffer_size = 0; - pcm->fd = -1; - free(pcm); - return 0; -} - -struct pcm *pcm_open(unsigned int card, unsigned int device, - unsigned int flags, struct pcm_config *config) -{ - struct pcm *pcm; - struct snd_pcm_info info; - struct snd_pcm_hw_params params; - struct snd_pcm_sw_params sparams; - char fn[256]; - int rc; - - pcm = calloc(1, sizeof(struct pcm)); - if (!pcm || !config) - return &bad_pcm; /* TODO: could support default config here */ - - pcm->config = *config; - - snprintf(fn, sizeof(fn), "/dev/snd/pcmC%uD%u%c", card, device, - flags & PCM_IN ? 'c' : 'p'); - - pcm->flags = flags; - pcm->fd = open(fn, O_RDWR); - if (pcm->fd < 0) { - oops(pcm, errno, "cannot open device '%s'", fn); - return pcm; - } - - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_INFO, &info)) { - oops(pcm, errno, "cannot get info"); - goto fail_close; - } - - param_init(¶ms); - param_set_mask(¶ms, SNDRV_PCM_HW_PARAM_FORMAT, - pcm_format_to_alsa(config->format)); - param_set_mask(¶ms, SNDRV_PCM_HW_PARAM_SUBFORMAT, - SNDRV_PCM_SUBFORMAT_STD); - param_set_min(¶ms, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, config->period_size); - param_set_int(¶ms, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - pcm_format_to_bits(config->format)); - param_set_int(¶ms, SNDRV_PCM_HW_PARAM_FRAME_BITS, - pcm_format_to_bits(config->format) * config->channels); - param_set_int(¶ms, SNDRV_PCM_HW_PARAM_CHANNELS, - config->channels); - param_set_int(¶ms, SNDRV_PCM_HW_PARAM_PERIODS, config->period_count); - param_set_int(¶ms, SNDRV_PCM_HW_PARAM_RATE, config->rate); - - if (flags & PCM_NOIRQ) { - - if (!(flags & PCM_MMAP)) { - oops(pcm, -EINVAL, "noirq only currently supported with mmap()."); - goto fail; - } - - params.flags |= SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP; - pcm->noirq_frames_per_msec = config->rate / 1000; - } - - if (flags & PCM_MMAP) - param_set_mask(¶ms, SNDRV_PCM_HW_PARAM_ACCESS, - SNDRV_PCM_ACCESS_MMAP_INTERLEAVED); - else - param_set_mask(¶ms, SNDRV_PCM_HW_PARAM_ACCESS, - SNDRV_PCM_ACCESS_RW_INTERLEAVED); - - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_PARAMS, ¶ms)) { - oops(pcm, errno, "cannot set hw params"); - goto fail_close; - } - - /* get our refined hw_params */ - config->period_size = param_get_int(¶ms, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); - config->period_count = param_get_int(¶ms, SNDRV_PCM_HW_PARAM_PERIODS); - pcm->buffer_size = config->period_count * config->period_size; - - if (flags & PCM_MMAP) { - pcm->mmap_buffer = mmap(NULL, pcm_frames_to_bytes(pcm, pcm->buffer_size), - PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, pcm->fd, 0); - if (pcm->mmap_buffer == MAP_FAILED) { - oops(pcm, -errno, "failed to mmap buffer %d bytes\n", - pcm_frames_to_bytes(pcm, pcm->buffer_size)); - goto fail_close; - } - } - - - memset(&sparams, 0, sizeof(sparams)); - sparams.tstamp_mode = SNDRV_PCM_TSTAMP_ENABLE; - sparams.period_step = 1; - sparams.avail_min = 1; - - if (!config->start_threshold) { - if (pcm->flags & PCM_IN) - pcm->config.start_threshold = sparams.start_threshold = 1; - else - pcm->config.start_threshold = sparams.start_threshold = - config->period_count * config->period_size / 2; - } else - sparams.start_threshold = config->start_threshold; - - /* pick a high stop threshold - todo: does this need further tuning */ - if (!config->stop_threshold) { - if (pcm->flags & PCM_IN) - pcm->config.stop_threshold = sparams.stop_threshold = - config->period_count * config->period_size * 10; - else - pcm->config.stop_threshold = sparams.stop_threshold = - config->period_count * config->period_size; - } - else - sparams.stop_threshold = config->stop_threshold; - - sparams.xfer_align = config->period_size / 2; /* needed for old kernels */ - sparams.silence_size = 0; - sparams.silence_threshold = config->silence_threshold; - pcm->boundary = sparams.boundary = pcm->buffer_size; - - while (pcm->boundary * 2 <= INT_MAX - pcm->buffer_size) - pcm->boundary *= 2; - - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)) { - oops(pcm, errno, "cannot set sw params"); - goto fail; - } - - rc = pcm_hw_mmap_status(pcm); - if (rc < 0) { - oops(pcm, rc, "mmap status failed"); - goto fail; - } - - pcm->underruns = 0; - return pcm; - -fail: - if (flags & PCM_MMAP) - munmap(pcm->mmap_buffer, pcm_frames_to_bytes(pcm, pcm->buffer_size)); -fail_close: - close(pcm->fd); - pcm->fd = -1; - return pcm; -} - -int pcm_is_ready(struct pcm *pcm) -{ - return pcm->fd >= 0; -} - -int pcm_start(struct pcm *pcm) -{ - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE) < 0) - return oops(pcm, errno, "cannot prepare channel"); - - if (pcm->flags & PCM_MMAP) - pcm_sync_ptr(pcm, 0); - - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START) < 0) - return oops(pcm, errno, "cannot start channel"); - - pcm->running = 1; - return 0; -} - -int pcm_stop(struct pcm *pcm) -{ - if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_DROP) < 0) - return oops(pcm, errno, "cannot stop channel"); - - pcm->running = 0; - return 0; -} - -static inline int pcm_mmap_playback_avail(struct pcm *pcm) -{ - int avail; - - avail = pcm->mmap_status->hw_ptr + pcm->buffer_size - pcm->mmap_control->appl_ptr; - - if (avail < 0) - avail += pcm->boundary; - else if (avail > (int)pcm->boundary) - avail -= pcm->boundary; - - return avail; -} - -static inline int pcm_mmap_capture_avail(struct pcm *pcm) -{ - int avail = pcm->mmap_status->hw_ptr - pcm->mmap_control->appl_ptr; - if (avail < 0) - avail += pcm->boundary; - return avail; -} - -static inline int pcm_mmap_avail(struct pcm *pcm) -{ - pcm_sync_ptr(pcm, SNDRV_PCM_SYNC_PTR_HWSYNC); - if (pcm->flags & PCM_IN) - return pcm_mmap_capture_avail(pcm); - else - return pcm_mmap_playback_avail(pcm); -} - -static void pcm_mmap_appl_forward(struct pcm *pcm, int frames) -{ - unsigned int appl_ptr = pcm->mmap_control->appl_ptr; - appl_ptr += frames; - - /* check for boundary wrap */ - if (appl_ptr > pcm->boundary) - appl_ptr -= pcm->boundary; - pcm->mmap_control->appl_ptr = appl_ptr; -} - -int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset, - unsigned int *frames) -{ - unsigned int continuous, copy_frames, avail; - - /* return the mmap buffer */ - *areas = pcm->mmap_buffer; - - /* and the application offset in frames */ - *offset = pcm->mmap_control->appl_ptr % pcm->buffer_size; - - avail = pcm_mmap_avail(pcm); - if (avail > pcm->buffer_size) - avail = pcm->buffer_size; - continuous = pcm->buffer_size - *offset; - - /* we can only copy frames if the are availabale and continuos */ - copy_frames = *frames; - if (copy_frames > avail) - copy_frames = avail; - if (copy_frames > continuous) - copy_frames = continuous; - *frames = copy_frames; - - return 0; -} - -int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames) -{ - (void)offset; - /* update the application pointer in userspace and kernel */ - pcm_mmap_appl_forward(pcm, frames); - pcm_sync_ptr(pcm, 0); - - return frames; -} - -int pcm_avail_update(struct pcm *pcm) -{ - pcm_sync_ptr(pcm, 0); - return pcm_mmap_avail(pcm); -} - -int pcm_state(struct pcm *pcm) -{ - int err = pcm_sync_ptr(pcm, 0); - if (err < 0) - return err; - - return pcm->mmap_status->state; -} - -int pcm_wait(struct pcm *pcm, int timeout) -{ - struct pollfd pfd; - int err; - - pfd.fd = pcm->fd; - pfd.events = POLLOUT | POLLERR | POLLNVAL; - - do { - /* let's wait for avail or timeout */ - err = poll(&pfd, 1, timeout); - if (err < 0) - return -errno; - - /* timeout ? */ - if (err == 0) - return 0; - - /* have we been interrupted ? */ - if (errno == -EINTR) - continue; - - /* check for any errors */ - if (pfd.revents & (POLLERR | POLLNVAL)) { - switch (pcm_state(pcm)) { - case PCM_STATE_XRUN: - return -EPIPE; - case PCM_STATE_SUSPENDED: - return -ESTRPIPE; - case PCM_STATE_DISCONNECTED: - return -ENODEV; - default: - return -EIO; - } - } - /* poll again if fd not ready for IO */ - } while (!(pfd.revents & (POLLIN | POLLOUT))); - - return 1; -} - -int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes) -{ - int err = 0, frames, avail; - unsigned int offset = 0, count; - - if (bytes == 0) - return 0; - - count = pcm_bytes_to_frames(pcm, bytes); - - while (count > 0) { - - /* get the available space for writing new frames */ - avail = pcm_avail_update(pcm); - if (avail < 0) { - fprintf(stderr, "cannot determine available mmap frames"); - return err; - } - - /* start the audio if we reach the threshold */ - if (!pcm->running && - (pcm->buffer_size - avail) >= pcm->config.start_threshold) { - if (pcm_start(pcm) < 0) { - fprintf(stderr, "start error: hw 0x%x app 0x%x avail 0x%x\n", - (unsigned int)pcm->mmap_status->hw_ptr, - (unsigned int)pcm->mmap_control->appl_ptr, - avail); - return -errno; - } - } - - /* sleep until we have space to write new frames */ - if (pcm->running && - (unsigned int)avail < pcm->mmap_control->avail_min) { - int time = -1; - - if (pcm->flags & PCM_NOIRQ) - time = (pcm->buffer_size - avail - pcm->mmap_control->avail_min) - / pcm->noirq_frames_per_msec; - - err = pcm_wait(pcm, time); - if (err < 0) { - pcm->running = 0; - fprintf(stderr, "wait error: hw 0x%x app 0x%x avail 0x%x\n", - (unsigned int)pcm->mmap_status->hw_ptr, - (unsigned int)pcm->mmap_control->appl_ptr, - avail); - pcm->mmap_control->appl_ptr = 0; - return err; - } - continue; - } - - frames = count; - if (frames > avail) - frames = avail; - - if (!frames) - break; - - /* copy frames from buffer */ - frames = pcm_mmap_write_areas(pcm, buffer, offset, frames); - if (frames < 0) { - fprintf(stderr, "write error: hw 0x%x app 0x%x avail 0x%x\n", - (unsigned int)pcm->mmap_status->hw_ptr, - (unsigned int)pcm->mmap_control->appl_ptr, - avail); - return frames; - } - - offset += frames; - count -= frames; - } - - return 0; -} diff --git a/firmware/target/hosted/android/system-android.c b/firmware/target/hosted/android/system-android.c index 6279504..d13b8d6 100644 --- a/firmware/target/hosted/android/system-android.c +++ b/firmware/target/hosted/android/system-android.c @@ -23,12 +23,6 @@ #include <setjmp.h> #include <jni.h> #include <pthread.h> -#if defined(DX50) || defined(DX90) -#include <stdlib.h> -#include <sys/reboot.h> -#include <sys/stat.h> -#include <stdio.h> -#endif /* DX50 || DX90 */ #include <unistd.h> #include "config.h" #include "system.h" @@ -37,83 +31,40 @@ -#if !defined(DX50) && !defined(DX90) /* global fields for use with various JNI calls */ static JavaVM *vm_ptr; JNIEnv *env_ptr; jobject RockboxService_instance; jclass RockboxService_class; -#endif /* !DX50 && !DX90 */ uintptr_t *stackbegin; uintptr_t *stackend; extern int main(void); -#if !defined(DX50) && !defined(DX90) extern void telephony_init_device(void); -#endif + void system_exception_wait(void) { -#if defined(DX50) || defined(DX90) - while(1); -#else intptr_t dummy = 0; while(button_read_device(&dummy) != BUTTON_BACK); -#endif /* DX50 || DX90 */ } void system_reboot(void) { -#if defined(DX50) || defined(DX90) - reboot(RB_AUTOBOOT); -#else power_off(); -#endif /* DX50 || DX90 */ } -#if !defined(DX50) && !defined(DX90) /* this is used to return from the entry point of the native library. */ static jmp_buf poweroff_buf; -#endif - void power_off(void) { -#if defined(DX50) || defined(DX90) - reboot(RB_POWER_OFF); -#else longjmp(poweroff_buf, 1); -#endif /* DX50 || DX90 */ } void system_init(void) { -#if defined(DX50) || defined(DX90) - volatile uintptr_t stack = 0; - stackbegin = stackend = (uintptr_t*) &stack; - - struct stat m1, m2; - stat("/mnt/", &m1); - do - { - /* waiting for storage to get mounted */ - stat("/sdcard/", &m2); - usleep(100000); - } - while(m1.st_dev == m2.st_dev); -/* here would be the correct place for 'system("/system/bin/muteopen");' (headphone-out relay) but in pcm-dx50.c, pcm_play_dma_start() - the output capacitors are charged already a bit and the click of the headphone-connection-relay is softer */ - -#if defined(DX90) - /* DAC needs to be unmuted on DX90 */ - FILE * f = fopen("/sys/class/codec/wm8740_mute", "w"); - fputc(0, f); - fclose(f); -#endif /* DX90 */ - -#else /* no better place yet */ telephony_init_device(); -#endif /* DX50 || DX90 */ } int hostfs_init(void) @@ -128,7 +79,6 @@ int hostfs_flush(void) return 0; } -#if !defined(DX50) && !defined(DX90) JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void* reserved) { @@ -169,7 +119,7 @@ Java_org_rockbox_RockboxService_main(JNIEnv *env, jobject this) /* simply return here. this will allow the VM to clean up objects and do * garbage collection */ } -#endif /* !DX50 && !DX90 */ + /* below is the facility for external (from other java threads) to safely call * into our snative code. When extracting rockbox.zip the main function is |