ubuntu 在 R40e 上 還有 Debian 在 Sempron 2600 上

2014年8月28日 星期四

asound.conf , route path,

/etc/asound.conf 有 alsa 裝置的配置開關.

有關 codec routing 部份.,,,

先看 driver 的 snd_soc_dapm_route 矩陣
.先把array copy 出來。
https://gist.github.com/checko/eb5fd55bfd7baa25ddd4

每個 element 有三個欄位. (OUT, SW, IN).

看 電路,決定一下 route 的 in, out.
以 play 來說,:
out 是 HPOL, HPOR.
input 是 I2S 第一組

找 array 中,OUT 欄位是 HPOL. HPOR 的..
 { "HPOL", NULL, "HP Amp" },
 { "HPOL", NULL, "HP L Amp" },
 { "HPOL", NULL, "Improve HP Amp Drv" },

 { "HPOR", NULL, "HP Amp" },
 { "HPOR", NULL, "HP R Amp" },
 { "HPOR", NULL, "Improve HP Amp Drv" },
所以可以知道HPO 可以有三個 input path 可以選 : HP AMP. HP L/R Amp, Improved HP Amp Drv

其中 HP L/R Amp 和 Improve HP Amp Drv 都沒有 input path, 只有 HP Amp 有:
 { "HP Amp", NULL, "HPO MIX" },
 { "HP Amp", NULL, "JD Power" },
 { "HP Amp", NULL, "Mic Det Power" },
一樣,其中只有 HPO MIX有 input source:
 { "HPO MIX", "DAC1 Switch", "DAC 1" },
 { "HPO MIX", "HPVOL Switch", "HPOVOL" },

HPOVOL 的話,要經過..
 { "HPOVOL", NULL, "HPOVOL MIXL" },
 { "HPOVOL", NULL, "HPOVOL MIXR" },
只看 HPOVOL MIXL (因為沒有要 swap L/R, or mono):
 { "HPOVOL MIXL", "DAC1 Switch", "DAC L1" },
 { "HPOVOL MIXL", "INL Switch", "INL VOL" },
有兩個選項,一個 DAC L1 (跟剛剛 HPO MIX 一樣), 另一個是 INL VOL

IN VOL 接到 Analog Input,所以不是我們要用的。
看 DAC L1:
 { "DAC L1", NULL, "Stereo DAC MIXL" },
 { "DAC L1", NULL, "PLL1", check_sysclk1_source },
其中 PLL1 會 trigger check_sysclk_source, 同時也沒有 input,所以只看 Stereo DAC MIXL:
 { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" },
 { "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" },
 { "Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" },
 { "Stereo DAC MIXL", NULL, "dac stereo1 filter" },
 { "Stereo DAC MIXL", NULL, "DAC L1 Power" },
DAC L1 Power 和 dac stereo1 filter 沒有 input,
IF1_DAC (也就是 I2S 第一組),有 0-7 共 8組 DAC...(!!)
DAC L1 接到 SounzReal, DAC L2 接到 Voice, 所以先看簡單的. DAC1 MIXL..
 { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" },
 { "DAC1 MIXL", "DAC1 Switch", "DAC1 L Mux" },
 { "DAC1 MIXL", NULL, "dac stereo1 filter" },
 { "DAC1 MIXL", NULL, "DAC L1 Power" },
dac stereo1 filter, DAC L1 Power 一樣,沒有 input.
Stereo1 ADC MIXL 接到 Analog Input ADC 哪一路,
所以應該是要看 DAC1 L Mux:
 { "DAC1 L Mux", "IF1 DAC", "IF1 DAC1 L" },
 { "DAC1 L Mux", "IF2 DAC", "IF2 DAC L" },
要 route 到 I2S 第一路,所以選 IF1 DAC1 L:
 { "IF1 DAC1 L", NULL, "IF1 DAC1" },
IF1 DAC1 的 source 有兩個:
 { "IF1 DAC1", NULL, "AIF1RX" },
 { "IF1 DAC1", NULL, "I2S1" },
好像就是最後了....
最後是..
#ifdef USE_ASRC
 {"I2S1", NULL, "ASRC enable"},
 {"I2S2", NULL, "ASRC enable"},
#endif

OK, 把上面的 path 列出來: (L)
 { "HPOL"           , NULL           , "HP Amp"          },
 { "HP Amp"         , NULL           , "HPO MIX"         },
 { "HPO MIX"        , "DAC1 Switch"  , "DAC 1"           },
 { "DAC 1"          , NULL           , "DAC L1"          },
 { "DAC L1"         , NULL           , "Stereo DAC MIXL" },
 { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL"       },
 { "DAC1 MIXL"      , "DAC1 Switch"  , "DAC1 L Mux"      },
 { "DAC1 L Mux"     , "IF1 DAC"      , "IF1 DAC1 L"      },
 { "IF1 DAC1 L"     , NULL           , "IF1 DAC1"        },
 { "IF1 DAC1"       , NULL           , "I2S1"            },
 { "I2S1"           , NULL           , "ASRC enable"     },
其中,中間一項不是 NULL 的,就要寫在 asound.conf 中..

寫的東西要用 tinymixer 來看...
tinymixer 會列出所有的 control gadge..

要設的有...
36 BOOL 1 HPO MIX DAC1 Switch                      On
62 BOOL 1 Stereo DAC MIXR DAC R1 Switch            On
65 BOOL 1 Stereo DAC MIXL DAC L1 Switch            On
73 BOOL 1 DAC1 MIXR DAC1 Switch                    On
75 BOOL 1 DAC1 MIXL DAC1 Switch                    On
68 ENUM 1 DAC1 R Mux                               IF1 DAC
69 ENUM 1 DAC1 L Mux                               IF1 DAC

所以 /etc/asound.conf 就是....

2014年8月26日 星期二

亂亂寫

dtsi 就是給 dts include 的 ?

2014年8月25日 星期一

加語系 -- android

支援的語系可以從: android/build/target/product/language_full.mk:
PRODUCT_LOCALES := en_US fr_FR it_IT es_ES de_DE nl_NL cs_CZ pl_PL ja_JP zh_TW zh_CN ru_RU ko_KR nb_NO es_US da_DK el_GR
tr_TR pt_PT pt_BR rm_CH sv_SE bg_BG ca_ES en_GB fi_FI hi_IN hr_HR hu_HU in_ID iw_IL lt_LT lv_LV ro_RO sk_SK sl_SI sr_RS 
uk_UA vi_VN tl_PH ar_EG fa_IR th_TH sw_TZ ms_MY af_ZA zu_ZA am_ET hi_IN
ref:

a whole set of __dev... macros are no longer used or defined

copy:
a whole set of __dev... macros are no longer used or defined

  • Here is the list: __devinit, __devinitdata, __devinitconst, __devexit, __devexitdata, __devexitconst
  • background: These attributes were used on certain driver functions and data declarations, putting them in a separate section that could be discarded under certain circumstances. This functionality is no longer relevant, and the macros were removed in version 3.8 of the kernel. The macros should no longer be used.
  • Just remove the attributes any place they are used.

ref:
  • http://elinux.org/Kernel_3.4_to_3.10_porting_guide
  • https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=54b956b903607
  • https://groups.google.com/forum/#!msg/linux.kernel/rHxmuN4tiE8/_LhGvxCjS18J

2014年8月19日 星期二

default.prop

就是在 android/build/core/Makefile:
# -----------------------------------------------------------------
# default.prop
INSTALLED_DEFAULT_PROP_TARGET := $(TARGET_ROOT_OUT)/default.prop
ALL_DEFAULT_INSTALLED_MODULES += $(INSTALLED_DEFAULT_PROP_TARGET)
ADDITIONAL_DEFAULT_PROPERTIES := \
    $(call collapse-pairs, $(ADDITIONAL_DEFAULT_PROPERTIES))
ADDITIONAL_DEFAULT_PROPERTIES += \
    $(call collapse-pairs, $(PRODUCT_DEFAULT_PROPERTY_OVERRIDES))
ADDITIONAL_DEFAULT_PROPERTIES := $(call uniq-pairs-by-first-component, \
    $(ADDITIONAL_DEFAULT_PROPERTIES),=)

$(INSTALLED_DEFAULT_PROP_TARGET):
        @echo Target buildinfo: $@
        @mkdir -p $(dir $@)
        $(hide) echo "#" > $@; \
                echo "# ADDITIONAL_DEFAULT_PROPERTIES" >> $@; \
                echo "#" >> $@;
        $(hide) $(foreach line,$(ADDITIONAL_DEFAULT_PROPERTIES), \
                echo "$(line)" >> $@;)
        build/tools/post_process_props.py $@

所以在所有 *.mk 中,有宣告 ADDITIONAL_DEFAULT_PROPERTY_OVERRIDES 的,都會被加入 default.prop 中。
例如:
android/devices/common/common.mk:
# Set default USB interface
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
        persist.sys.usb.config=mass_storage \
        persist.sys.strictmode.disable=1

另外,script 又多加處理某些部份,寫在 build/tools/post_process_props.py:
# Put the modifications that you need to make into the /system/build.prop into this
# function. The prop object has get(name) and put(name,value) methods.
def mangle_default_prop(prop):
  # If ro.debuggable is 1, then enable adb on USB by default
  # (this is for userdebug builds)
  if prop.get("ro.debuggable") == "1":
    val = prop.get("persist.sys.usb.config")
    if val == "":
      val = "adb"
    else:
      val = val + ",adb"
    prop.put("persist.sys.usb.config", val)
  # UsbDeviceManager expects a value here.  If it doesn't get it, it will
  # default to "adb". That might not the right policy there, but it's better
  # to be explicit.
  if not prop.get("persist.sys.usb.config"):
    prop.put("persist.sys.usb.config", "none");

他加上 persist.sys.usb.config adb

所以最後 rootfs/default.prop 就有:
persist.sys.usb.config=mass_storage,adb

2014年8月18日 星期一

/* SoC machine DAI configuration, glues a codec and cpu DAI together */
struct snd_soc_pcm_runtime {
 struct device *dev;
 struct snd_soc_card *card;
 struct snd_soc_dai_link *dai_link;
 struct mutex pcm_mutex;
 enum snd_soc_pcm_subclass pcm_subclass;
 struct snd_pcm_ops ops;

 unsigned int dev_registered:1;

 /* Dynamic PCM BE runtime data */
 struct snd_soc_dpcm_runtime dpcm[2];

 long pmdown_time;
 unsigned char pop_wait:1;

 /* runtime devices */
 struct snd_pcm *pcm;
 struct snd_compr *compr;
 struct snd_soc_codec *codec;
 struct snd_soc_platform *platform;
 struct snd_soc_dai *codec_dai;
 struct snd_soc_dai *cpu_dai;

 struct delayed_work delayed_work;
#ifdef CONFIG_DEBUG_FS
 struct dentry *debugfs_dpcm_root;
 struct dentry *debugfs_dpcm_state;
#endif
};
還有 soc_soc_dai_link:
struct snd_soc_dai_link {
 /* config - must be set by machine driver */
 const char *name;   /* Codec name */
 const char *stream_name;  /* Stream name */
 /*
  * You MAY specify the link's CPU-side device, either by device name,
  * or by DT/OF node, but not both. If this information is omitted,
  * the CPU-side DAI is matched using .cpu_dai_name only, which hence
  * must be globally unique. These fields are currently typically used
  * only for codec to codec links, or systems using device tree.
  */
 const char *cpu_name;
 const struct device_node *cpu_of_node;
 /*
  * You MAY specify the DAI name of the CPU DAI. If this information is
  * omitted, the CPU-side DAI is matched using .cpu_name/.cpu_of_node
  * only, which only works well when that device exposes a single DAI.
  */
 const char *cpu_dai_name;
 /*
  * You MUST specify the link's codec, either by device name, or by
  * DT/OF node, but not both.
  */
 const char *codec_name;
 const struct device_node *codec_of_node;
 /* You MUST specify the DAI name within the codec */
 const char *codec_dai_name;
 /*
  * You MAY specify the link's platform/PCM/DMA driver, either by
  * device name, or by DT/OF node, but not both. Some forms of link
  * do not need a platform.
  */
 const char *platform_name;
 const struct device_node *platform_of_node;
 int be_id; /* optional ID for machine driver BE identification */

 const struct snd_soc_pcm_stream *params;

 unsigned int dai_fmt;           /* format to set on init */

 enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */

 /* Keep DAI active over suspend */
 unsigned int ignore_suspend:1;

 /* Symmetry requirements */
 unsigned int symmetric_rates:1;

 /* Do not create a PCM for this DAI link (Backend link) */
 unsigned int no_pcm:1;

 /* This DAI link can route to other DAI links at runtime (Frontend)*/
 unsigned int dynamic:1;

 /* pmdown_time is ignored at stop */
 unsigned int ignore_pmdown_time:1;

 /* codec/machine specific init - e.g. add machine controls */
 int (*init)(struct snd_soc_pcm_runtime *rtd);

 /* optional hw_params re-writing for BE and FE sync */
 int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd,
   struct snd_pcm_hw_params *params);

 /* machine stream operations */
 const struct snd_soc_ops *ops;
 const struct snd_soc_compr_ops *compr_ops;
};

2014年8月14日 星期四

convert mp3 to wav file , stereo 48000

因為 sound codec 只吃 48k, stereo 的 wav 檔。
所以就要自己轉檔。

感覺還是 command line 的比較好用。
 mpg123 -o output --stereo -r 48000 1kHz.mp3
這樣就能強制把 mp3 轉成 48k, 2 channel (stereo) 的 wav 檔。
-- 用 man 可以看所有 option.
ref:
  • http://www.cyberciti.biz/faq/convert-mp3-files-to-wav-files-in-linux/

2014年8月13日 星期三

libtinyalsa.so 同時給 tinyplay 和 audioflinger link
debug 的時候, fprintf(srtderr,"..

但是在 Dalvik 中,會把 stdout, stderr 重導到 /dev/null
所以看不到。

http://developer.android.com/tools/debugging/debugging-log.html#viewingStd

說,可以用 setprop log.redirect-stdio true 來叫 dalvik 把 stdout, stderr 重導到 logcat

看一下 code...

2014年8月12日 星期二

worklog - tinyalsa, tinyplay

變成 tinyalsa.
tinyplay -- pcm_open()

struct pcm *pcm_open(unsigned int card,  unsigned int device,
                     unsigned int flags, struct pcm_config *config)
{
   ...
   ...
   snprintf(fn , sizeof(fn), "/dev/snd?pcmC%dD%u%c", card, device, flags & PCM_IN ? 'c' : 'p');
   ...
   pcm->fb = open(fn, O_RDWR);

在 android/external/tinyalsa 下

build 出:
  • libtinyalsa.so
  • tinyplay
  • tinycap
  • tinymix

kernel:

include/uapi/sound/asound.h:
struct snd_interval {
 unsigned int min, max;
 unsigned int openmin:1,
              openmax:1,
              integer:1,
              empty:1;
};

是在:
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]; /* reserved masks */
 struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
 struct snd_interval ires[9]; /* reserved intervals */
 unsigned int rmask;          /* W: requested masks */
 unsigned int cmask;          /* R: changed masks */
 unsigned int info;           /* R: Info flags for returned setup */
 unsigned int msbits;         /* R: used most significant bits */
 unsigned int rate_num;       /* R: rate numerator */
 unsigned int rate_den;       /* R: rate denominator */
 snd_pcm_uframes_t fifo_size; /* R: chip FIFO size in frames */
 unsigned char reserved[64];  /* reserved for future */
};

Android AudioHardware 可以正常 pcm_open( )
tinyplay 就 fail

/AudioHardware open 時的 config:
         struct pcm_config config = {
            channels : 2,
            rate : 48000,
            period_size : 1024,
            period_count : 2,
            format : PCM_FORMAT_S16_LE,
            start_threshold : 0,
            stop_threshold : 0,
            silence_threshold : 0,
        };


在 target board 上,tinyplay pcm_open failed 的原因都是 config 內容不符合 codec support 的範圍。
pcm_open( ) 是 tinyalsa library function (pcm.c).

其中依次是:
  • fd = open("pcmC0D0p",O_RDWR)
  • ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info)
  • ioctl(fd, SNDRV_PCM_IOCTL_HW_PARAMS, ¶ms)
  • ioctl(fd, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)
config 內容不支援,是在 IOCTL_HW_PARAMS 時出錯。

打開 kernel/sound/pcm_native.c 的 RULES_DEBUG 還有掉 printk 的 KERN_DEBUG 後,

kernel msg 會有:
 SAMPLE_BITS = [16 16] -> [16 16]
 FRAME_BITS = [32 32] -> [32 32]
 CHANNELS = [1 1] -> empty
這樣就知道是 channels 沒有 match (codec 只 support 2 channels)
改用 2 channels (stereo) 的 sample wav file 後...
 ..
 ..
 PERIODS = [4 4] -> empty
這就是 period number 參數不對。
還好 tinyplay 有 optio "-n" 可以指定。
加上 -n 2 後,就沒有問題了。

2014年8月6日 星期三

Kingmax uhs i 32g

Pc 家 399 ?

Broway usb 3.0 4port hub

結果沒有附 adaptor,
附的是 usb power cable.....


因為是加價購買的,$249

標籤

網誌存檔