title: Getting ARM/WM8350 audio and power management working in linux
body: <p>I have a rooted Sony prs900, running a linux 2.6.23 #2 PREEMPT kernel, for <strong>ARMv6</strong>. (Montavista linux kernel).  I'm having problems with figuring out how power management works, both for running the system and for powering up and down the audio port.
  I can neither figure out how to read the battery/powerline status information, nor get the audio chip to play sound, etc ... although I have been studying the kernel modules for a while...</p>
  
  <p>It's worth a little money for help, say $100 paypal donation to an email account, (or more if this takes a long time...) for the first person able to explain to me how to do them in a way that works.
  Eg: read battery status, and change some power modes like getting the audio amplifiers to power up/down so that the audio played to <code>/dev/dsp</code> (oss emulation) actually comes out as sound rather than just being consumed by the chip and ignored...</p>
  
  <p>The actual sony kernel, and binary packages of cross compiler tools are located on the <a href="http://www.sony.net/Products/Linux/Audio/PRS-900.html" rel="nofollow">main page</a>.   <a href="http://www.sony.net/Products/Linux/Audio/Download/PRS-900/linux-2.6.23_091126.tgz" rel="nofollow">Actual kernel sourcecode</a> is also available.</p>
  
  <hr>
  
  <p>What I have learned so far myself :</p>
  
  <p>The sony is using a wolfson micro WM8350 audio driver and battery charger/power management chip for all the system's power; eg: it can power down/up the SD memory cards, send more power to the cpu, power up audio amplifiers, etc. See: <a href="http://www.wolfsonmicro.com/documents/uploads/data_sheets/en/WM8350.pdf" rel="nofollow">WM8350 Datasheet</a>.  </p>
  
  <p>Pretty much, the whole problem revolves around getting the WM8350 kernel drivers to work...
  Although the company brags quite a bit about it's support under linux, they don't have any application notes or examples that are actually <em>helpful</em> that I can find, other than the datasheet.  I suspect the kernel drivers I have are beta code, because they don't seem to be behaving well (several error messages in the kernel log about wm8350 registers not being readable happen at every boot even when running only the sony's native software...).</p>
  
  <p>The kernel driver's source-code of most interest are in:  linux-2.6.23_091126/drivers/mxc/pmic/{core,wm8350}
  Notice, the wm8350 is a competitor to the MC14783, but the linux kernel drivers use the same {core} driver source code for both chips; The sony ONLY has the wm8350 on it -- there is no MC14783 present.</p>
  
  <p>The code that I most want most desperately to understand how to make operate is found in the subdirectory {wm8350}, eg: wm8350/wm8350pm/power_supply_sysfs.c.</p>
  
  <p>I want the audio to fire up too, but 'm not quite sure where the pertinent audio amplifier code is yet...</p>
  
  <p>Very clearly the wm8350pm code is designed to export a /sys directory interface; right now /sys is mounted and operational on the system; but I'm not very familiar with the semantics of these newer style interfaces... they aren't quite like the old APM power interfaces for Linux laptops...</p>
  
  <p>First I checked the obvious:
  If I do a "cat /sys/power/state"  it returns the word "mem" and nothing else.
  The file has permissions <code>-rw-r--r--</code>, so potentially it could be written -- but I don't know with what.  The string "mem" does not exist anywhere in the source code for the wm8350pm drivers, so I don't even know if /sys/power/state is part of the source code.</p>
  
  <p>Doing a find /sys -iname "<em>wm8350</em>" reveals a handful of directories with the patterns:
   wm8350-rtc , wm8350-pmic , wm8350-bl , wm8350-power , wm8350-led 
   wm8350-hifi-dai , wm8350-codec
   wm8350-imx32ads.0 </p>
  
  <p>So, I do an ls-l on each directory, and look for actual files rather than symbolic links or subdirectories, and what I find are stock useless writable files:  bind, unbind, uevent,</p>
  
  <p>and a very few read only files: pmic_reg, dapm_widget, modalias, codec_reg which aren't very helpful.</p>
  
  <p>It's no surprise that:</p>
  
  <p>Doing: cat /sys/devices/platform/wm8350-ebx5016-audi/modalias gives "wm8350-ebx5016-audio"</p>
  
  <p>Doing: cat /sys/devices/platform/wm8350-imx32ads.0/modalias gives "wm8350-imx32ads"</p>
  
  <p>and since audio is off... Doing: cat /sys/devices/platform/wm8350-ebx5016-audi/dapm_widget reveals the audio state:</p>
  
  <pre><code>Headphone Jack: Off
  Line In Jack: On
  Mic Bias: Off
  Left DAC: Off
  Right DAC: Off
  ... (all else off and omitted except )...
  EBX5016-hifi: PM State: D3hot
  </code></pre>
  
  <p>The last two files, I expect should do wm8350 chip register dumps... and one did.
  Doing: cat /sys/devices/wm8350-pmic/pmic-reg causes a long pause, then nothing is printed.
  but:
  Doing: cat /sys/devices/wm8350/platform/wm8350-ebx5016-audi/wm8350-codec/codec_reg does prints a list of registers up to e8 which is just a few bytes larger than the datasheet says the chip should be (0x00 to 0xe6).</p>
  
  <p>I tried using a python program to play wav files, (works on my desktop computer), and I noticed that /dev/dsp does open, the mixers <em>DO</em> set volume levels, and nothing comes out.  So -- the audio driver is not able to enable the sound amplifiers on it's own automatically.</p>
  
  <p>There are no alsa sound files in /dev, nor are any alsa tools found on the embedded machine... so I assume Sony is strictly using OSS /dev/dsp and /dev/mixer.</p>
  
  <p>There is only one other access point I can find to the ws8350:
  There <em>IS</em> a device driver /dev/wm8350.   </p>
  
  <p>That driver created by the source code in subdirectory wm8350/wm8350_reg.c  ; in theory it should be able to read and write to all registers using ioctls() calls from a user space.  However, something appears grossly wrong with it, for I wrote a test program to read the wm8350 registers... and most of the registers return error messages rather than allowing to be read, including the most pulic ID registers (0x00, 0x01) etc.</p>
  
  <p>So, I'm quite stuck.  Pointers, thoughts, hints, are quite desired.</p>