Bugzilla – Bug 12871
Headphone detect unreliable with 4-conductor headphone
Last modified: 2009-09-08 09:14:21 UTC
The headphone detect works in an odd manner with 4 conductor headphones (on PA5 units). Prior to PA5, 4 conductor headphones did not work correctly. The device should be able to distinguish between 3 and 4 conductor headphones. When a 3 conductor headphone is inserted, the software reads '1'. When no headphone is inserted it reads '0'. When a 4 conductor is inserted is sometimes reads 1 and sometimes 3. Measuring voltages, the following was observed. Micbias set to 2.5V No headphone inserted, the shield measures 1.8V (unexpected) 3-wire inserted: 0.0V (expected) 4-wire inserted: 2.0V (unexpected). Headphone detect reliable with 3-wire, but unreliable differentiation between 3 and 4 wire By removing R486, it operation is as expected: No headphones inserted: shield measures 2.5V 3-Wire: 0.0V 4-wire: 2.0V (microhpone drawing some current). Headphone detect non-functional (Because it's disconnected) By shorting R486: No headphones inserted: 1.8V 3-Wire: 0.0V 4-Wire: 2.08V Headphone detect reliable with 3-wire, but unreliable differentiation between 3 and 4 wire For some reason the micbias output switches between 1.8 and 2.5, depending on whether or not something is inserted. The register changes that happen on insert are: AIC3104 WRITE 65: 00000009 AIC3104 WRITE 93: 00000008 AIC3104 WRITE 51: 0000000d AIC3104 WRITE 86: 00000008 On removal: AIC3104 WRITE 65: 00000008 AIC3104 WRITE 93: 00000009 AIC3104 WRITE 51: 0000000c AIC3104 WRITE 86: 00000009
Created attachment 5467 [details] 3 wire inserted, reads 3-wire
Created attachment 5468 [details] 3 wire inserted, reads 4-wire
Created attachment 5469 [details] 4 wire inserted, reads 3-wire detected
Created attachment 5470 [details] 4 wire inserted, reads 4-wire detected
Proof-of-concept fix in baby-mp r6628. However, Richard should probably rework the fix so that there are 3 status bits reported back to user space: headset detected (boolean) headset type (00, 01, or 11), button pressed (boolean) In order to do this detection properly, the headset detect circuitry needs to be turned off and on, which resets the sticky headset type register. This was fixed in mp because we need to make sure that it's reliable in SZ for production.
Fixed in baby-mp r6636. I don't have a headset for testing this. To unit test the kernel code use: ### This gets the headphone state, 0=none, 1=headphone, 3=headphone+mic # amixer cget name="Headphone Switch" numid=39,iface=MIXER,name='Headphone Switch' ; type=INTEGER,access=rw------,values=1,min=0,max=0,step=0 : values=0 ### This gets the headphone button state # amixer cget name="Headphone Button" numid=40,iface=MIXER,name='Headphone Button' ; type=INTEGER,access=rw------,values=1,min=0,max=0,step=0 : values=0 ### This listens for events (so when you plug in or press the button you should see the output: # amixer events & ### This is printed when the headphone is inserted (any type) event value: numid=39,iface=MIXER,name='Headphone Switch' ### This is printed when the headphone button is pressed event value: numid=??,iface=MIXER,name='Headphone Button'