Add: ac101 dsp_a mode, playing 2 in 8 channels OK
This commit is contained in:
parent
7aae0e3353
commit
aec1941ae1
5 changed files with 1180 additions and 160 deletions
844
ac101-ok-20180119.state
Normal file
844
ac101-ok-20180119.state
Normal file
|
@ -0,0 +1,844 @@
|
||||||
|
state.seeed8micvoicec {
|
||||||
|
control.1 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 ADC timeslot 0 volume'
|
||||||
|
value.0 252
|
||||||
|
value.1 252
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 2
|
||||||
|
range '0 - 255'
|
||||||
|
dbmin -11925
|
||||||
|
dbmax 7200
|
||||||
|
dbvalue.0 6975
|
||||||
|
dbvalue.1 6975
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.2 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 ADC timeslot 1 volume'
|
||||||
|
value.0 255
|
||||||
|
value.1 255
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 2
|
||||||
|
range '0 - 255'
|
||||||
|
dbmin -11925
|
||||||
|
dbmax 7200
|
||||||
|
dbvalue.0 7200
|
||||||
|
dbvalue.1 7200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.3 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 DAC timeslot 0 volume'
|
||||||
|
value.0 189
|
||||||
|
value.1 189
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 2
|
||||||
|
range '0 - 255'
|
||||||
|
dbmin -11925
|
||||||
|
dbmax 7200
|
||||||
|
dbvalue.0 2250
|
||||||
|
dbvalue.1 2250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.4 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 DAC timeslot 1 volume'
|
||||||
|
value.0 189
|
||||||
|
value.1 189
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 2
|
||||||
|
range '0 - 255'
|
||||||
|
dbmin -11925
|
||||||
|
dbmax 7200
|
||||||
|
dbvalue.0 2250
|
||||||
|
dbvalue.1 2250
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.5 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 ADC timeslot 0 mixer gain'
|
||||||
|
value.0 15
|
||||||
|
value.1 15
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 2
|
||||||
|
range '0 - 15'
|
||||||
|
dbmin -600
|
||||||
|
dbmax 8400
|
||||||
|
dbvalue.0 8400
|
||||||
|
dbvalue.1 8400
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.6 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 ADC timeslot 1 mixer gain'
|
||||||
|
value.0 3
|
||||||
|
value.1 3
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 2
|
||||||
|
range '0 - 3'
|
||||||
|
dbmin -600
|
||||||
|
dbmax 1200
|
||||||
|
dbvalue.0 1200
|
||||||
|
dbvalue.1 1200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.7 {
|
||||||
|
iface MIXER
|
||||||
|
name 'ADC volume'
|
||||||
|
value.0 172
|
||||||
|
value.1 172
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 2
|
||||||
|
range '0 - 255'
|
||||||
|
dbmin -11925
|
||||||
|
dbmax 7200
|
||||||
|
dbvalue.0 975
|
||||||
|
dbvalue.1 975
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.8 {
|
||||||
|
iface MIXER
|
||||||
|
name 'DAC volume'
|
||||||
|
value.0 0
|
||||||
|
value.1 0
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 2
|
||||||
|
range '0 - 255'
|
||||||
|
dbmin -11925
|
||||||
|
dbmax 7200
|
||||||
|
dbvalue.0 -11925
|
||||||
|
dbvalue.1 -11925
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.9 {
|
||||||
|
iface MIXER
|
||||||
|
name 'DAC mixer gain'
|
||||||
|
value.0 10
|
||||||
|
value.1 10
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 2
|
||||||
|
range '0 - 15'
|
||||||
|
dbmin -600
|
||||||
|
dbmax 8400
|
||||||
|
dbvalue.0 5400
|
||||||
|
dbvalue.1 5400
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.10 {
|
||||||
|
iface MIXER
|
||||||
|
name 'digital volume'
|
||||||
|
value 3
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 1
|
||||||
|
range '0 - 63'
|
||||||
|
dbmin -7308
|
||||||
|
dbmax 0
|
||||||
|
dbvalue.0 -6960
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.11 {
|
||||||
|
iface MIXER
|
||||||
|
name 'ADC input gain'
|
||||||
|
value.0 5
|
||||||
|
value.1 5
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 2
|
||||||
|
range '0 - 7'
|
||||||
|
dbmin -450
|
||||||
|
dbmax 600
|
||||||
|
dbvalue.0 300
|
||||||
|
dbvalue.1 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.12 {
|
||||||
|
iface MIXER
|
||||||
|
name 'MIC1 boost amplifier gain'
|
||||||
|
value 4
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 1
|
||||||
|
range '0 - 7'
|
||||||
|
dbmin 0
|
||||||
|
dbmax 1400
|
||||||
|
dbvalue.0 800
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.13 {
|
||||||
|
iface MIXER
|
||||||
|
name 'MIC2 boost amplifier gain'
|
||||||
|
value 5
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 1
|
||||||
|
range '0 - 7'
|
||||||
|
dbmin 0
|
||||||
|
dbmax 1400
|
||||||
|
dbvalue.0 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.14 {
|
||||||
|
iface MIXER
|
||||||
|
name 'LINEINL-LINEINR pre-amplifier gain'
|
||||||
|
value 4
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 1
|
||||||
|
range '0 - 7'
|
||||||
|
dbmin -1200
|
||||||
|
dbmax 900
|
||||||
|
dbvalue.0 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.15 {
|
||||||
|
iface MIXER
|
||||||
|
name 'MIC1 BST stage to L_R outp mixer gain'
|
||||||
|
value 3
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 1
|
||||||
|
range '0 - 7'
|
||||||
|
dbmin -450
|
||||||
|
dbmax 600
|
||||||
|
dbvalue.0 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.16 {
|
||||||
|
iface MIXER
|
||||||
|
name 'MIC2 BST stage to L_R outp mixer gain'
|
||||||
|
value 3
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 1
|
||||||
|
range '0 - 7'
|
||||||
|
dbmin -450
|
||||||
|
dbmax 600
|
||||||
|
dbvalue.0 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.17 {
|
||||||
|
iface MIXER
|
||||||
|
name 'LINEINL/R to L_R output mixer gain'
|
||||||
|
value 4
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 1
|
||||||
|
range '0 - 7'
|
||||||
|
dbmin -450
|
||||||
|
dbmax 600
|
||||||
|
dbvalue.0 150
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.18 {
|
||||||
|
iface MIXER
|
||||||
|
name 'speaker volume'
|
||||||
|
value 27
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 1
|
||||||
|
range '0 - 31'
|
||||||
|
dbmin -4800
|
||||||
|
dbmax -150
|
||||||
|
dbvalue.0 -750
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.19 {
|
||||||
|
iface MIXER
|
||||||
|
name 'headphone volume'
|
||||||
|
value 53
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type INTEGER
|
||||||
|
count 1
|
||||||
|
range '0 - 63'
|
||||||
|
dbmin -6300
|
||||||
|
dbmax 0
|
||||||
|
dbvalue.0 -1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.20 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1OUT0L Mux'
|
||||||
|
value SUM_AIF1AD0L_AIF1AD0R
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 AIF1_AD0L
|
||||||
|
item.1 AIF1_AD0R
|
||||||
|
item.2 SUM_AIF1AD0L_AIF1AD0R
|
||||||
|
item.3 AVE_AIF1AD0L_AIF1AD0R
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.21 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1OUT0R Mux'
|
||||||
|
value SUM_AIF1AD0L_AIF1AD0R
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 AIF1_AD0R
|
||||||
|
item.1 AIF1_AD0L
|
||||||
|
item.2 SUM_AIF1AD0L_AIF1AD0R
|
||||||
|
item.3 AVE_AIF1AD0L_AIF1AD0R
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.22 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1OUT1L Mux'
|
||||||
|
value SUM_AIF1ADC1L_AIF1ADC1R
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 AIF1_AD1L
|
||||||
|
item.1 AIF1_AD1R
|
||||||
|
item.2 SUM_AIF1ADC1L_AIF1ADC1R
|
||||||
|
item.3 AVE_AIF1ADC1L_AIF1ADC1R
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.23 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1OUT1R Mux'
|
||||||
|
value SUM_AIF1ADC1L_AIF1ADC1R
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 AIF1_AD1R
|
||||||
|
item.1 AIF1_AD1L
|
||||||
|
item.2 SUM_AIF1ADC1L_AIF1ADC1R
|
||||||
|
item.3 AVE_AIF1ADC1L_AIF1ADC1R
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.24 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1IN0L Mux'
|
||||||
|
value AIF1_DA0L
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 AIF1_DA0L
|
||||||
|
item.1 AIF1_DA0R
|
||||||
|
item.2 SUM_AIF1DA0L_AIF1DA0R
|
||||||
|
item.3 AVE_AIF1DA0L_AIF1DA0R
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.25 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1IN0R Mux'
|
||||||
|
value AIF1_DA0R
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 AIF1_DA0R
|
||||||
|
item.1 AIF1_DA0L
|
||||||
|
item.2 SUM_AIF1DA0L_AIF1DA0R
|
||||||
|
item.3 AVE_AIF1DA0L_AIF1DA0R
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.26 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1IN1L Mux'
|
||||||
|
value SUM_AIF1DA1L_AIF1DA1R
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 AIF1_DA1L
|
||||||
|
item.1 AIF1_DA1R
|
||||||
|
item.2 SUM_AIF1DA1L_AIF1DA1R
|
||||||
|
item.3 AVE_AIF1DA1L_AIF1DA1R
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.27 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1IN1R Mux'
|
||||||
|
value SUM_AIF1DA1L_AIF1DA1R
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 AIF1_DA1R
|
||||||
|
item.1 AIF1_DA1L
|
||||||
|
item.2 SUM_AIF1DA1L_AIF1DA1R
|
||||||
|
item.3 AVE_AIF1DA1L_AIF1DA1R
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.28 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 AD0L Mixer AIF1 DA0L Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.29 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 AD0L Mixer ADCL Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.30 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 AD0R Mixer AIF1 DA0R Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.31 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 AD0R Mixer ADCR Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.32 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 AD1L Mixer ADCL Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.33 {
|
||||||
|
iface MIXER
|
||||||
|
name 'AIF1 AD1R Mixer ADCR Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.34 {
|
||||||
|
iface MIXER
|
||||||
|
name 'DACL Mixer ADCL Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.35 {
|
||||||
|
iface MIXER
|
||||||
|
name 'DACL Mixer AIF1DA1L Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.36 {
|
||||||
|
iface MIXER
|
||||||
|
name 'DACL Mixer AIF1DA0L Switch'
|
||||||
|
value true
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.37 {
|
||||||
|
iface MIXER
|
||||||
|
name 'DACR Mixer ADCR Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.38 {
|
||||||
|
iface MIXER
|
||||||
|
name 'DACR Mixer AIF1DA1R Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.39 {
|
||||||
|
iface MIXER
|
||||||
|
name 'DACR Mixer AIF1DA0R Switch'
|
||||||
|
value true
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.40 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Left Output Mixer DACR Switch'
|
||||||
|
value true
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.41 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Left Output Mixer DACL Switch'
|
||||||
|
value true
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.42 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Left Output Mixer LINEINL Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.43 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Left Output Mixer LINEINL-LINEINR Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.44 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Left Output Mixer MIC2Booststage Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.45 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Left Output Mixer MIC1Booststage Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.46 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Right Output Mixer DACL Switch'
|
||||||
|
value true
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.47 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Right Output Mixer DACR Switch'
|
||||||
|
value true
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.48 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Right Output Mixer LINEINR Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.49 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Right Output Mixer LINEINL-LINEINR Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.50 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Right Output Mixer MIC2Booststage Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.51 {
|
||||||
|
iface MIXER
|
||||||
|
name 'Right Output Mixer MIC1Booststage Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.52 {
|
||||||
|
iface MIXER
|
||||||
|
name 'HP_R Mux'
|
||||||
|
value 'DACR HPR Switch'
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 'DACR HPR Switch'
|
||||||
|
item.1 'Right Analog Mixer HPR Switch'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.53 {
|
||||||
|
iface MIXER
|
||||||
|
name 'HP_L Mux'
|
||||||
|
value 'DACL HPL Switch'
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 'DACL HPL Switch'
|
||||||
|
item.1 'Left Analog Mixer HPL Switch'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.54 {
|
||||||
|
iface MIXER
|
||||||
|
name 'SPK_R Mux'
|
||||||
|
value 'MIXER Switch'
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 'MIXER Switch'
|
||||||
|
item.1 'MIXR MIXL Switch'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.55 {
|
||||||
|
iface MIXER
|
||||||
|
name 'SPK_L Mux'
|
||||||
|
value 'MIXEL Switch'
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 'MIXEL Switch'
|
||||||
|
item.1 'MIXL MIXR Switch'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.56 {
|
||||||
|
iface MIXER
|
||||||
|
name 'LEFT ADC input Mixer MIC1 boost Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.57 {
|
||||||
|
iface MIXER
|
||||||
|
name 'LEFT ADC input Mixer MIC2 boost Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.58 {
|
||||||
|
iface MIXER
|
||||||
|
name 'LEFT ADC input Mixer LININL-R Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.59 {
|
||||||
|
iface MIXER
|
||||||
|
name 'LEFT ADC input Mixer LINEINL Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.60 {
|
||||||
|
iface MIXER
|
||||||
|
name 'LEFT ADC input Mixer Lout_Mixer_Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.61 {
|
||||||
|
iface MIXER
|
||||||
|
name 'LEFT ADC input Mixer Rout_Mixer_Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.62 {
|
||||||
|
iface MIXER
|
||||||
|
name 'RIGHT ADC input Mixer MIC1 boost Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.63 {
|
||||||
|
iface MIXER
|
||||||
|
name 'RIGHT ADC input Mixer MIC2 boost Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.64 {
|
||||||
|
iface MIXER
|
||||||
|
name 'RIGHT ADC input Mixer LINEINL-R Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.65 {
|
||||||
|
iface MIXER
|
||||||
|
name 'RIGHT ADC input Mixer LINEINR Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.66 {
|
||||||
|
iface MIXER
|
||||||
|
name 'RIGHT ADC input Mixer Rout_Mixer_Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.67 {
|
||||||
|
iface MIXER
|
||||||
|
name 'RIGHT ADC input Mixer Lout_Mixer_Switch'
|
||||||
|
value false
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type BOOLEAN
|
||||||
|
count 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.68 {
|
||||||
|
iface MIXER
|
||||||
|
name 'MIC2 SRC'
|
||||||
|
value none
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 none
|
||||||
|
item.1 MIC2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.69 {
|
||||||
|
iface MIXER
|
||||||
|
name 'ADCL Mux'
|
||||||
|
value ADC
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 ADC
|
||||||
|
item.1 DMIC
|
||||||
|
}
|
||||||
|
}
|
||||||
|
control.70 {
|
||||||
|
iface MIXER
|
||||||
|
name 'ADCR Mux'
|
||||||
|
value ADC
|
||||||
|
comment {
|
||||||
|
access 'read write'
|
||||||
|
type ENUMERATED
|
||||||
|
count 1
|
||||||
|
item.0 ADC
|
||||||
|
item.1 DMIC
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
360
ac101.c
360
ac101.c
|
@ -26,27 +26,26 @@
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/switch.h>
|
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/timer.h>
|
#include <linux/timer.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <mach/gpio.h>
|
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <mach/gpio.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
#include "ac101.h"
|
#include "ac101.h"
|
||||||
|
|
||||||
|
|
||||||
//#define CONFIG_SWITCH_DETECT_EXTERNAL
|
#define CONFIG_SWITCH_DETECT_EXTERNAL
|
||||||
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
||||||
static volatile int reset_flag = 0;
|
static volatile int reset_flag = 0;
|
||||||
static int hook_flag1 = 0;
|
static int hook_flag1 = 0;
|
||||||
static int hook_flag2 = 0;
|
static int hook_flag2 = 0;
|
||||||
static int KEY_VOLUME_FLAG = 0;
|
static int KEY_VOLUME_FLAG = 0;
|
||||||
/*1=headphone in slot, else 0*/
|
/* 1=headphone in slot, 0 else */
|
||||||
static int headphone_state = 0;
|
static int headphone_state = 0;
|
||||||
static volatile int irq_flag = 0;
|
static volatile int irq_flag = 0;
|
||||||
static struct workqueue_struct *switch_detect_queue;
|
static struct workqueue_struct *switch_detect_queue;
|
||||||
|
@ -59,7 +58,8 @@ static struct workqueue_struct *codec_irq_queue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define PA_CTL 205
|
//#define PA_CTL 205
|
||||||
|
#define PA_CTL 0
|
||||||
#define I2C_BUS 1
|
#define I2C_BUS 1
|
||||||
|
|
||||||
/*Default initialize configuration*/
|
/*Default initialize configuration*/
|
||||||
|
@ -87,9 +87,14 @@ static int adc_digital_val = 0;
|
||||||
static bool agc_used = false;
|
static bool agc_used = false;
|
||||||
static bool drc_used = false;
|
static bool drc_used = false;
|
||||||
|
|
||||||
#define ac10x_RATES (SNDRV_PCM_RATE_8000_192000|SNDRV_PCM_RATE_KNOT)
|
#define ac10x_RATES (SNDRV_PCM_RATE_8000_96000|SNDRV_PCM_RATE_KNOT)
|
||||||
#define ac10x_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
|
#define ac10x_FORMATS ( SNDRV_PCM_FMTBIT_S8 | \
|
||||||
SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
|
SNDRV_PCM_FMTBIT_S16_LE | \
|
||||||
|
/* SNDRV_PCM_FMTBIT_S18_3LE | \
|
||||||
|
SNDRV_PCM_FMTBIT_S20_3LE | \
|
||||||
|
SNDRV_PCM_FMTBIT_S24_LE | \
|
||||||
|
SNDRV_PCM_FMTBIT_S32_LE*/ \
|
||||||
|
0)
|
||||||
|
|
||||||
enum headphone_mode_u {
|
enum headphone_mode_u {
|
||||||
HEADPHONE_IDLE,
|
HEADPHONE_IDLE,
|
||||||
|
@ -108,9 +113,12 @@ static const char *ac10x_supplies[] = {
|
||||||
|
|
||||||
/*struct for ac10x*/
|
/*struct for ac10x*/
|
||||||
struct ac10x_priv {
|
struct ac10x_priv {
|
||||||
//struct ac100 *ac10x;
|
|
||||||
struct snd_soc_codec *codec;
|
struct snd_soc_codec *codec;
|
||||||
|
|
||||||
|
unsigned sysclk;
|
||||||
|
|
||||||
|
struct regmap* regmap;
|
||||||
|
|
||||||
struct mutex dac_mutex;
|
struct mutex dac_mutex;
|
||||||
struct mutex adc_mutex;
|
struct mutex adc_mutex;
|
||||||
u8 dac_enable;
|
u8 dac_enable;
|
||||||
|
@ -124,6 +132,7 @@ struct ac10x_priv {
|
||||||
int num_supplies;
|
int num_supplies;
|
||||||
struct regulator_bulk_data *supplies;
|
struct regulator_bulk_data *supplies;
|
||||||
|
|
||||||
|
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
||||||
/*headset*/
|
/*headset*/
|
||||||
int virq; /*headset irq*/
|
int virq; /*headset irq*/
|
||||||
struct switch_dev sdev;
|
struct switch_dev sdev;
|
||||||
|
@ -131,6 +140,7 @@ struct ac10x_priv {
|
||||||
int check_count;
|
int check_count;
|
||||||
int check_count_sum;
|
int check_count_sum;
|
||||||
int reset_flag;
|
int reset_flag;
|
||||||
|
#endif
|
||||||
|
|
||||||
enum headphone_mode_u mode;
|
enum headphone_mode_u mode;
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
|
@ -317,7 +327,7 @@ void drc_enable(struct snd_soc_codec *codec,bool on)
|
||||||
{
|
{
|
||||||
int reg_val;
|
int reg_val;
|
||||||
if (on) {
|
if (on) {
|
||||||
snd_soc_write(codec, 0xb5, 0x80);
|
snd_soc_write(codec, 0xb5, 0xA080);
|
||||||
reg_val = snd_soc_read(codec, MOD_CLK_ENA);
|
reg_val = snd_soc_read(codec, MOD_CLK_ENA);
|
||||||
reg_val |= (0x1<<6);
|
reg_val |= (0x1<<6);
|
||||||
snd_soc_write(codec, MOD_CLK_ENA, reg_val);
|
snd_soc_write(codec, MOD_CLK_ENA, reg_val);
|
||||||
|
@ -369,7 +379,7 @@ void set_configuration(struct snd_soc_codec *codec)
|
||||||
static int late_enable_dac(struct snd_soc_dapm_widget *w,
|
static int late_enable_dac(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = w->codec;
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
mutex_lock(&ac10x->dac_mutex);
|
mutex_lock(&ac10x->dac_mutex);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -380,6 +390,7 @@ static int late_enable_dac(struct snd_soc_dapm_widget *w,
|
||||||
snd_soc_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_DAC_DIG), (0x1<<MOD_CLK_DAC_DIG));
|
snd_soc_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_DAC_DIG), (0x1<<MOD_CLK_DAC_DIG));
|
||||||
snd_soc_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_DAC_DIG), (0x1<<MOD_RESET_DAC_DIG));
|
snd_soc_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_DAC_DIG), (0x1<<MOD_RESET_DAC_DIG));
|
||||||
snd_soc_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENDA), (0x1<<ENDA));
|
snd_soc_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENDA), (0x1<<ENDA));
|
||||||
|
snd_soc_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENHPF),(0x1<<ENHPF));
|
||||||
}
|
}
|
||||||
ac10x->dac_enable++;
|
ac10x->dac_enable++;
|
||||||
break;
|
break;
|
||||||
|
@ -387,6 +398,7 @@ static int late_enable_dac(struct snd_soc_dapm_widget *w,
|
||||||
if (ac10x->dac_enable > 0){
|
if (ac10x->dac_enable > 0){
|
||||||
ac10x->dac_enable--;
|
ac10x->dac_enable--;
|
||||||
if (ac10x->dac_enable == 0){
|
if (ac10x->dac_enable == 0){
|
||||||
|
snd_soc_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENHPF),(0x0<<ENHPF));
|
||||||
snd_soc_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENDA), (0x0<<ENDA));
|
snd_soc_update_bits(codec, DAC_DIG_CTRL, (0x1<<ENDA), (0x0<<ENDA));
|
||||||
/*disable dac module clk*/
|
/*disable dac module clk*/
|
||||||
snd_soc_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_DAC_DIG), (0x0<<MOD_CLK_DAC_DIG));
|
snd_soc_update_bits(codec, MOD_CLK_ENA, (0x1<<MOD_CLK_DAC_DIG), (0x0<<MOD_CLK_DAC_DIG));
|
||||||
|
@ -402,7 +414,7 @@ static int late_enable_dac(struct snd_soc_dapm_widget *w,
|
||||||
static int late_enable_adc(struct snd_soc_dapm_widget *w,
|
static int late_enable_adc(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = w->codec;
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
mutex_lock(&ac10x->adc_mutex);
|
mutex_lock(&ac10x->adc_mutex);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
@ -434,19 +446,24 @@ static int ac10x_speaker_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *k,
|
struct snd_kcontrol *k,
|
||||||
int event)
|
int event)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = w->codec;
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
AC10X_DBG("[speaker open ]%s,line:%d\n",__func__,__LINE__);
|
AC10X_DBG("[speaker open ]%s,line:%d\n",__func__,__LINE__);
|
||||||
if (drc_used) {
|
if (drc_used) {
|
||||||
drc_enable(codec,1);
|
drc_enable(codec,1);
|
||||||
}
|
}
|
||||||
|
#if PA_CTL
|
||||||
msleep(30);
|
msleep(30);
|
||||||
gpio_set_value(PA_CTL, 1);
|
gpio_set_value(PA_CTL, 1);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SND_SOC_DAPM_PRE_PMD :
|
case SND_SOC_DAPM_PRE_PMD :
|
||||||
AC10X_DBG("[speaker close ]%s,line:%d\n",__func__,__LINE__);
|
AC10X_DBG("[speaker close ]%s,line:%d\n",__func__,__LINE__);
|
||||||
|
#if PA_CTL
|
||||||
gpio_set_value(PA_CTL, 0);
|
gpio_set_value(PA_CTL, 0);
|
||||||
|
#endif
|
||||||
if (drc_used) {
|
if (drc_used) {
|
||||||
drc_enable(codec,0);
|
drc_enable(codec,0);
|
||||||
}
|
}
|
||||||
|
@ -459,7 +476,7 @@ static int ac10x_speaker_event(struct snd_soc_dapm_widget *w,
|
||||||
static int ac10x_headphone_event(struct snd_soc_dapm_widget *w,
|
static int ac10x_headphone_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *k, int event)
|
struct snd_kcontrol *k, int event)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = w->codec;
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_POST_PMU:
|
case SND_SOC_DAPM_POST_PMU:
|
||||||
/*open*/
|
/*open*/
|
||||||
|
@ -483,8 +500,12 @@ static int ac10x_headphone_event(struct snd_soc_dapm_widget *w,
|
||||||
int ac10x_aif1clk(struct snd_soc_dapm_widget *w,
|
int ac10x_aif1clk(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = w->codec;
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
|
|
||||||
|
AC10X_DBG("%s() L%d event=%d pre_up/%d post_down/%d\n", __func__, __LINE__,
|
||||||
|
event, SND_SOC_DAPM_PRE_PMU, SND_SOC_DAPM_POST_PMD);
|
||||||
|
|
||||||
mutex_lock(&ac10x->aifclk_mutex);
|
mutex_lock(&ac10x->aifclk_mutex);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
|
@ -523,7 +544,7 @@ int ac10x_aif1clk(struct snd_soc_dapm_widget *w,
|
||||||
static int dmic_mux_ev(struct snd_soc_dapm_widget *w,
|
static int dmic_mux_ev(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol, int event)
|
struct snd_kcontrol *kcontrol, int event)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = w->codec;
|
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||||
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
switch (event){
|
switch (event){
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
|
@ -829,12 +850,11 @@ static const char *adc_mux_text[] = {
|
||||||
"ADC",
|
"ADC",
|
||||||
"DMIC",
|
"DMIC",
|
||||||
};
|
};
|
||||||
static const struct soc_enum adc_enum =
|
static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text);
|
||||||
SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
|
|
||||||
static const struct snd_kcontrol_new adcl_mux =
|
static const struct snd_kcontrol_new adcl_mux =
|
||||||
SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
|
SOC_DAPM_ENUM("ADCL Mux", adc_enum);
|
||||||
static const struct snd_kcontrol_new adcr_mux =
|
static const struct snd_kcontrol_new adcr_mux =
|
||||||
SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
|
SOC_DAPM_ENUM("ADCR Mux", adc_enum);
|
||||||
|
|
||||||
/*built widget*/
|
/*built widget*/
|
||||||
static const struct snd_soc_dapm_widget ac10x_dapm_widgets[] = {
|
static const struct snd_soc_dapm_widget ac10x_dapm_widgets[] = {
|
||||||
|
@ -932,8 +952,8 @@ static const struct snd_soc_dapm_widget ac10x_dapm_widgets[] = {
|
||||||
SND_SOC_DAPM_SPK("External Speaker", ac10x_speaker_event),
|
SND_SOC_DAPM_SPK("External Speaker", ac10x_speaker_event),
|
||||||
|
|
||||||
/*DMIC*/
|
/*DMIC*/
|
||||||
SND_SOC_DAPM_VIRT_MUX("ADCL Mux", SND_SOC_NOPM, 0, 0, &adcl_mux),
|
SND_SOC_DAPM_MUX("ADCL Mux", SND_SOC_NOPM, 0, 0, &adcl_mux),
|
||||||
SND_SOC_DAPM_VIRT_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, &adcr_mux),
|
SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, &adcr_mux),
|
||||||
|
|
||||||
SND_SOC_DAPM_PGA_E("DMICL VIR", SND_SOC_NOPM, 0, 0, NULL, 0,
|
SND_SOC_DAPM_PGA_E("DMICL VIR", SND_SOC_NOPM, 0, 0, NULL, 0,
|
||||||
dmic_mux_ev, SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
|
dmic_mux_ev, SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
|
||||||
|
@ -1102,19 +1122,22 @@ struct pll_div {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct aif1_fs {
|
struct aif1_fs {
|
||||||
unsigned int samplerate;
|
unsigned samp_rate;
|
||||||
int aif1_bclk_div;
|
int bclk_div;
|
||||||
int aif1_srbit;
|
int srbit;
|
||||||
|
#define _SERIES_24_576K 0
|
||||||
|
#define _SERIES_22_579K 1
|
||||||
|
int series;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct aif1_lrck {
|
struct aif1_lrck {
|
||||||
int aif1_lrlk_div;
|
int div;
|
||||||
int aif1_lrlk_bit;
|
int bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct aif1_word_size {
|
struct aif1_word_size {
|
||||||
int aif1_wsize_val;
|
int val;
|
||||||
int aif1_wsize_bit;
|
int bit;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1129,6 +1152,7 @@ static const struct pll_div codec_pll_div[] = {
|
||||||
{6000000, 22579200, 38, 429, 0},/*((429+0*0.2)*6000000)/(38*(2*1+1))*/
|
{6000000, 22579200, 38, 429, 0},/*((429+0*0.2)*6000000)/(38*(2*1+1))*/
|
||||||
{13000000, 22579200, 19, 99, 0},
|
{13000000, 22579200, 19, 99, 0},
|
||||||
{19200000, 22579200, 25, 88, 1},
|
{19200000, 22579200, 25, 88, 1},
|
||||||
|
{24000000, 22579200, 63, 177, 4},/*((177 + 4 * 0.2) * 24000000) / (63 * (2 * 1 + 1)) */
|
||||||
{128000, 24576000, 1, 576, 0},
|
{128000, 24576000, 1, 576, 0},
|
||||||
{192000, 24576000, 1, 384, 0},
|
{192000, 24576000, 1, 384, 0},
|
||||||
{256000, 24576000, 1, 288, 0},
|
{256000, 24576000, 1, 288, 0},
|
||||||
|
@ -1138,22 +1162,22 @@ static const struct pll_div codec_pll_div[] = {
|
||||||
{6000000, 24576000, 25, 307, 1},
|
{6000000, 24576000, 25, 307, 1},
|
||||||
{13000000, 24576000, 42, 238, 1},
|
{13000000, 24576000, 42, 238, 1},
|
||||||
{19200000, 24576000, 25, 96, 0},
|
{19200000, 24576000, 25, 96, 0},
|
||||||
|
{24000000, 24576000, 39, 119, 4},/*((119 + 4 * 0.2) * 24000000) / (39 * (2 * 1 + 1)) */
|
||||||
{11289600, 22579200, 1, 6, 0},
|
{11289600, 22579200, 1, 6, 0},
|
||||||
{12288000, 24576000, 1, 6, 0},
|
{12288000, 24576000, 1, 6, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aif1_fs codec_aif1_fs[] = {
|
static const struct aif1_fs codec_aif1_fs[] = {
|
||||||
{44100, 4, 7},
|
{44100, 2, 7, _SERIES_22_579K},
|
||||||
{48000, 4, 8},
|
{48000, 2, 8},
|
||||||
{8000, 9, 0},
|
{8000, 12, 0},
|
||||||
{11025, 8, 1},
|
{11025, 8, 1, _SERIES_22_579K},
|
||||||
{12000, 8, 2},
|
{12000, 8, 2},
|
||||||
{16000, 7, 3},
|
{16000, 6, 3},
|
||||||
{22050, 6, 4},
|
{22050, 4, 4, _SERIES_22_579K},
|
||||||
{24000, 6, 5},
|
{24000, 4, 5},
|
||||||
{32000, 5, 6},
|
/* {32000, 3, 6}, not support */
|
||||||
{96000, 2, 9},
|
{96000, 1, 9},
|
||||||
{192000, 1, 10},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct aif1_lrck codec_aif1_lrck[] = {
|
static const struct aif1_lrck codec_aif1_lrck[] = {
|
||||||
|
@ -1169,24 +1193,34 @@ static const struct aif1_word_size codec_aif1_wsize[] = {
|
||||||
{16, 1},
|
{16, 1},
|
||||||
{20, 2},
|
{20, 2},
|
||||||
{24, 3},
|
{24, 3},
|
||||||
|
{32, 3},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned ac10x_bclkdivs[] = {
|
||||||
|
1, 2, 4, 6,
|
||||||
|
8, 12, 16, 24,
|
||||||
|
32, 48, 64, 96,
|
||||||
|
128, 192, 0, 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int ac10x_aif_mute(struct snd_soc_dai *codec_dai, int mute)
|
static int ac10x_aif_mute(struct snd_soc_dai *codec_dai, int mute)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_codec *codec = codec_dai->codec;
|
||||||
if(mute){
|
|
||||||
snd_soc_write(codec, DAC_VOL_CTRL, 0);
|
AC10X_DBG("%s() L%d mute=%d\n", __func__, __LINE__, mute);
|
||||||
}else{
|
|
||||||
snd_soc_write(codec, DAC_VOL_CTRL, 0xa0a0);
|
snd_soc_write(codec, DAC_VOL_CTRL, mute? 0: 0xA0A0);
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ac10x_aif_shutdown(struct snd_pcm_substream *substream,
|
static void ac10x_aif_shutdown(struct snd_pcm_substream *substream,
|
||||||
struct snd_soc_dai *codec_dai)
|
struct snd_soc_dai *codec_dai)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_codec *codec = codec_dai->codec;
|
||||||
int reg_val;
|
int reg_val;
|
||||||
|
|
||||||
AC10X_DBG("%s,line:%d\n", __func__, __LINE__);
|
AC10X_DBG("%s,line:%d\n", __func__, __LINE__);
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||||
if(agc_used){
|
if(agc_used){
|
||||||
agc_enable(codec, 0);
|
agc_enable(codec, 0);
|
||||||
|
@ -1196,11 +1230,13 @@ static void ac10x_aif_shutdown(struct snd_pcm_substream *substream,
|
||||||
if (codec_dai->playback_active && dmic_used && reg_val == 0x4) {
|
if (codec_dai->playback_active && dmic_used && reg_val == 0x4) {
|
||||||
snd_soc_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), (0x7<<AIF1_FS));
|
snd_soc_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), (0x7<<AIF1_FS));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ac10x_set_pll(struct snd_soc_dai *codec_dai, int pll_id, int source,
|
||||||
|
unsigned int freq_in, unsigned int freq_out);
|
||||||
|
|
||||||
static int ac10x_hw_params(struct snd_pcm_substream *substream,
|
static int ac10x_hw_params(struct snd_pcm_substream *substream,
|
||||||
struct snd_pcm_hw_params *params,
|
struct snd_pcm_hw_params *params,
|
||||||
struct snd_soc_dai *codec_dai)
|
struct snd_soc_dai *codec_dai)
|
||||||
|
@ -1208,34 +1244,47 @@ static int ac10x_hw_params(struct snd_pcm_substream *substream,
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int AIF_CLK_CTRL = 0;
|
int AIF_CLK_CTRL = 0;
|
||||||
int aif1_word_size = 16;
|
int aif1_word_size = 16;
|
||||||
int aif1_lrlk_div = 64;
|
int aif1_lrck_div = 64;
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_codec *codec = codec_dai->codec;
|
||||||
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
|
int reg_val, freq_out;
|
||||||
|
unsigned channels;
|
||||||
|
|
||||||
|
AC10X_DBG("%s() L%d +++\n", __func__, __LINE__);
|
||||||
|
|
||||||
|
channels = params_channels(params);
|
||||||
|
|
||||||
switch (codec_dai->id) {
|
switch (codec_dai->id) {
|
||||||
case 1:
|
case AIF1_CLK:
|
||||||
AIF_CLK_CTRL = AIF1_CLK_CTRL;
|
AIF_CLK_CTRL = AIF1_CLK_CTRL;
|
||||||
aif1_lrlk_div = 64;
|
aif1_lrck_div = 16 * channels;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(codec_aif1_lrck); i++) {
|
for (i = 0; i < ARRAY_SIZE(codec_aif1_lrck); i++) {
|
||||||
if (codec_aif1_lrck[i].aif1_lrlk_div == aif1_lrlk_div) {
|
if (codec_aif1_lrck[i].div == aif1_lrck_div) {
|
||||||
snd_soc_update_bits(codec, AIF_CLK_CTRL, (0x7<<AIF1_LRCK_DIV), ((codec_aif1_lrck[i].aif1_lrlk_bit)<<AIF1_LRCK_DIV));
|
snd_soc_update_bits(codec, AIF_CLK_CTRL, (0x7<<AIF1_LRCK_DIV), ((codec_aif1_lrck[i].bit)<<AIF1_LRCK_DIV));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freq_out = 24576000;
|
||||||
for (i = 0; i < ARRAY_SIZE(codec_aif1_fs); i++) {
|
for (i = 0; i < ARRAY_SIZE(codec_aif1_fs); i++) {
|
||||||
if (codec_aif1_fs[i].samplerate == params_rate(params)) {
|
if (codec_aif1_fs[i].samp_rate == params_rate(params)) {
|
||||||
if (codec_dai->capture_active && dmic_used && codec_aif1_fs[i].samplerate == 44100) {
|
if (codec_dai->capture_active && dmic_used && codec_aif1_fs[i].samp_rate == 44100) {
|
||||||
snd_soc_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), (0x4<<AIF1_FS));
|
snd_soc_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), (0x4<<AIF1_FS));
|
||||||
} else
|
} else {
|
||||||
snd_soc_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), ((codec_aif1_fs[i].aif1_srbit)<<AIF1_FS));
|
snd_soc_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), ((codec_aif1_fs[i].srbit)<<AIF1_FS));
|
||||||
snd_soc_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF2_FS), ((codec_aif1_fs[i].aif1_srbit)<<AIF2_FS));
|
}
|
||||||
snd_soc_update_bits(codec, AIF_CLK_CTRL, (0xf<<AIF1_BCLK_DIV), ((codec_aif1_fs[i].aif1_bclk_div)<<AIF1_BCLK_DIV));
|
if (codec_aif1_fs[i].series == _SERIES_22_579K)
|
||||||
|
freq_out = 22579200;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* set I2S word size */
|
||||||
switch (params_format(params)) {
|
switch (params_format(params)) {
|
||||||
case SNDRV_PCM_FORMAT_S24_LE:
|
case SNDRV_PCM_FORMAT_S24_LE:
|
||||||
case SNDRV_PCM_FORMAT_S32_LE:
|
case SNDRV_PCM_FORMAT_S32_LE:
|
||||||
|
@ -1247,11 +1296,39 @@ static int ac10x_hw_params(struct snd_pcm_substream *substream,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (i = 0; i < ARRAY_SIZE(codec_aif1_wsize); i++) {
|
for (i = 0; i < ARRAY_SIZE(codec_aif1_wsize); i++) {
|
||||||
if (codec_aif1_wsize[i].aif1_wsize_val == aif1_word_size) {
|
if (codec_aif1_wsize[i].val == aif1_word_size) {
|
||||||
snd_soc_update_bits(codec, AIF_CLK_CTRL, (0x3<<AIF1_WORK_SIZ), ((codec_aif1_wsize[i].aif1_wsize_bit)<<AIF1_WORK_SIZ));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
snd_soc_update_bits(codec, AIF_CLK_CTRL, (0x3<<AIF1_WORK_SIZ), ((codec_aif1_wsize[i].bit)<<AIF1_WORK_SIZ));
|
||||||
|
|
||||||
|
/* set TDM slot size, fixed 32 bits */
|
||||||
|
#if 0
|
||||||
|
if ((i = codec_aif1_wsize[i].bit) > 2)
|
||||||
|
#endif
|
||||||
|
i = 2;
|
||||||
|
snd_soc_update_bits(codec, AIF1_ADCDAT_CTRL, 0x3 << AIF1_SLOT_SIZ, i << AIF1_SLOT_SIZ);
|
||||||
|
|
||||||
|
/* setting pll if it's master mode */
|
||||||
|
reg_val = snd_soc_read(codec, AIF_CLK_CTRL);
|
||||||
|
if ((reg_val & (0x1 << AIF1_MSTR_MOD)) == 0) {
|
||||||
|
unsigned bclkdiv;
|
||||||
|
|
||||||
|
|
||||||
|
ac10x_set_pll(codec_dai, AC10X_MCLK1, 0, ac10x->sysclk, freq_out);
|
||||||
|
|
||||||
|
bclkdiv = freq_out / (aif1_lrck_div * params_rate(params));
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ac10x_bclkdivs) - 1; i++) {
|
||||||
|
if (ac10x_bclkdivs[i] >= bclkdiv) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_soc_update_bits(codec, AIF_CLK_CTRL, (0xf<<AIF1_BCLK_DIV), i<<AIF1_BCLK_DIV);
|
||||||
|
}
|
||||||
|
|
||||||
|
AC10X_DBG("%s() L%d ---\n", __func__, __LINE__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,10 +1336,18 @@ static int ac10x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||||
int clk_id, unsigned int freq, int dir)
|
int clk_id, unsigned int freq, int dir)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_codec *codec = codec_dai->codec;
|
||||||
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
|
|
||||||
|
AC10X_DBG("%s,line:%d, id=%d freq=%d, dir=%d\n", __func__, __LINE__,
|
||||||
|
clk_id, freq, dir);
|
||||||
|
#if 0
|
||||||
|
struct snd_soc_codec *codec = codec_dai->codec;
|
||||||
|
|
||||||
switch (clk_id) {
|
switch (clk_id) {
|
||||||
case AIF1_CLK:
|
case AIF1_CLK:
|
||||||
AC10X_DBG("%s,line:%d,snd_soc_read(codec, SYSCLK_CTRL):%x\n", __func__, __LINE__, snd_soc_read(codec, SYSCLK_CTRL));
|
AC10X_DBG("%s,line:%d,snd_soc_read(codec, SYSCLK_CTRL):%x\n",
|
||||||
|
__func__, __LINE__,
|
||||||
|
snd_soc_read(codec, SYSCLK_CTRL));
|
||||||
/*system clk from aif1*/
|
/*system clk from aif1*/
|
||||||
snd_soc_update_bits(codec, SYSCLK_CTRL, (0x1<<SYSCLK_SRC), (0x0<<SYSCLK_SRC));
|
snd_soc_update_bits(codec, SYSCLK_CTRL, (0x1<<SYSCLK_SRC), (0x0<<SYSCLK_SRC));
|
||||||
break;
|
break;
|
||||||
|
@ -1273,6 +1358,9 @@ static int ac10x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
ac10x->sysclk = freq;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1283,34 +1371,40 @@ static int ac10x_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||||
int AIF_CLK_CTRL = 0;
|
int AIF_CLK_CTRL = 0;
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_codec *codec = codec_dai->codec;
|
||||||
|
|
||||||
|
AC10X_DBG("%s() L%d\n", __func__, __LINE__);
|
||||||
|
|
||||||
switch (codec_dai->id) {
|
switch (codec_dai->id) {
|
||||||
case 1:
|
case AIF1_CLK:
|
||||||
AC10X_DBG("%s,line:%d\n", __func__, __LINE__);
|
|
||||||
AIF_CLK_CTRL = AIF1_CLK_CTRL;
|
AIF_CLK_CTRL = AIF1_CLK_CTRL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
AC10X_DBG("%s,line:%d\n", __func__, __LINE__);
|
|
||||||
/*
|
/*
|
||||||
* master or slave selection
|
* master or slave selection
|
||||||
* 0 = Master mode
|
* 0 = Master mode
|
||||||
* 1 = Slave mode
|
* 1 = Slave mode
|
||||||
*/
|
*/
|
||||||
reg_val = snd_soc_read(codec, AIF_CLK_CTRL);
|
reg_val = snd_soc_read(codec, AIF_CLK_CTRL);
|
||||||
reg_val &=~(0x1<<AIF1_MSTR_MOD);
|
reg_val &= ~(0x1<<AIF1_MSTR_MOD);
|
||||||
switch(fmt & SND_SOC_DAIFMT_MASTER_MASK){
|
switch(fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||||
case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master, ap is slave*/
|
case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master, ap is slave*/
|
||||||
reg_val |= (0x0<<AIF1_MSTR_MOD);
|
reg_val |= (0x0<<AIF1_MSTR_MOD);
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave,ap is master*/
|
case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave, ap is master*/
|
||||||
reg_val |= (0x1<<AIF1_MSTR_MOD);
|
reg_val |= (0x1<<AIF1_MSTR_MOD);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("unknwon master/slave format\n");
|
pr_err("unknwon master/slave format\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable TDM mode
|
||||||
|
*/
|
||||||
|
// reg_val |= (0x1 << AIF1_TDMM_ENA);
|
||||||
|
reg_val &= ~(0x1 << AIF1_TDMM_ENA);
|
||||||
snd_soc_write(codec, AIF_CLK_CTRL, reg_val);
|
snd_soc_write(codec, AIF_CLK_CTRL, reg_val);
|
||||||
|
|
||||||
/* i2s mode selection */
|
/* i2s mode selection */
|
||||||
|
@ -1360,16 +1454,17 @@ static int ac10x_set_dai_fmt(struct snd_soc_dai *codec_dai,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ac10x_set_fll(struct snd_soc_dai *codec_dai, int pll_id, int source,
|
static int ac10x_set_pll(struct snd_soc_dai *codec_dai, int pll_id, int source,
|
||||||
unsigned int freq_in, unsigned int freq_out)
|
unsigned int freq_in, unsigned int freq_out)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int m = 0;
|
int m = 0;
|
||||||
int n_i = 0;
|
int n_i = 0;
|
||||||
int n_f = 0;
|
int n_f = 0;
|
||||||
|
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_codec *codec = codec_dai->codec;
|
||||||
|
|
||||||
AC10X_DBG("%s, line:%d, pll_id:%d\n", __func__, __LINE__, pll_id);
|
AC10X_DBG("%s, line:%d, pll_id:%d\n", __func__, __LINE__, pll_id);
|
||||||
|
|
||||||
if (!freq_out)
|
if (!freq_out)
|
||||||
return 0;
|
return 0;
|
||||||
if ((freq_in < 128000) || (freq_in > 24576000)) {
|
if ((freq_in < 128000) || (freq_in > 24576000)) {
|
||||||
|
@ -1379,11 +1474,9 @@ static int ac10x_set_fll(struct snd_soc_dai *codec_dai, int pll_id, int source,
|
||||||
case AC10X_MCLK1:
|
case AC10X_MCLK1:
|
||||||
/*select aif1 clk source from mclk1*/
|
/*select aif1 clk source from mclk1*/
|
||||||
snd_soc_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF1CLK_SRC), (0x0<<AIF1CLK_SRC));
|
snd_soc_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF1CLK_SRC), (0x0<<AIF1CLK_SRC));
|
||||||
snd_soc_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF2CLK_SRC), (0x0<<AIF2CLK_SRC));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1415,9 +1508,8 @@ static int ac10x_set_fll(struct snd_soc_dai *codec_dai, int pll_id, int source,
|
||||||
snd_soc_update_bits(codec, PLL_CTRL2, (0x7<<PLL_POSTDIV_NF), (n_f<<PLL_POSTDIV_NF));
|
snd_soc_update_bits(codec, PLL_CTRL2, (0x7<<PLL_POSTDIV_NF), (n_f<<PLL_POSTDIV_NF));
|
||||||
snd_soc_update_bits(codec, PLL_CTRL2, (0x1<<PLL_EN), (1<<PLL_EN));
|
snd_soc_update_bits(codec, PLL_CTRL2, (0x1<<PLL_EN), (1<<PLL_EN));
|
||||||
/*enable pll_enable*/
|
/*enable pll_enable*/
|
||||||
snd_soc_update_bits(codec, SYSCLK_CTRL, (0x1<<PLLCLK_ENA), (1<<PLLCLK_ENA));
|
snd_soc_update_bits(codec, SYSCLK_CTRL, (0x1<<PLLCLK_ENA), (0x1<<PLLCLK_ENA));
|
||||||
snd_soc_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF1CLK_SRC), (0x3<<AIF1CLK_SRC));
|
snd_soc_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF1CLK_SRC), (0x3<<AIF1CLK_SRC));
|
||||||
snd_soc_update_bits(codec, SYSCLK_CTRL, (0x3<<AIF2CLK_SRC), (0x3<<AIF2CLK_SRC));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1426,7 +1518,9 @@ static int ac10x_audio_startup(struct snd_pcm_substream *substream,
|
||||||
struct snd_soc_dai *codec_dai)
|
struct snd_soc_dai *codec_dai)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = codec_dai->codec;
|
struct snd_soc_codec *codec = codec_dai->codec;
|
||||||
|
|
||||||
AC10X_DBG("%s,line:%d\n", __func__, __LINE__);
|
AC10X_DBG("%s,line:%d\n", __func__, __LINE__);
|
||||||
|
|
||||||
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
||||||
if(agc_used){
|
if(agc_used){
|
||||||
agc_enable(codec, 1);
|
agc_enable(codec, 1);
|
||||||
|
@ -1496,7 +1590,7 @@ static int ac10x_set_bias_level(struct snd_soc_codec *codec,
|
||||||
AC10X_DBG("%s,line:%d, SND_SOC_BIAS_OFF\n", __func__, __LINE__);
|
AC10X_DBG("%s,line:%d, SND_SOC_BIAS_OFF\n", __func__, __LINE__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
codec->dapm.bias_level = level;
|
snd_soc_codec_get_dapm(codec)->bias_level = level;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static const struct snd_soc_dai_ops ac10x_aif1_dai_ops = {
|
static const struct snd_soc_dai_ops ac10x_aif1_dai_ops = {
|
||||||
|
@ -1505,7 +1599,7 @@ static const struct snd_soc_dai_ops ac10x_aif1_dai_ops = {
|
||||||
.hw_params = ac10x_hw_params,
|
.hw_params = ac10x_hw_params,
|
||||||
.shutdown = ac10x_aif_shutdown,
|
.shutdown = ac10x_aif_shutdown,
|
||||||
.digital_mute = ac10x_aif_mute,
|
.digital_mute = ac10x_aif_mute,
|
||||||
.set_pll = ac10x_set_fll,
|
.set_pll = ac10x_set_pll,
|
||||||
.startup = ac10x_audio_startup,
|
.startup = ac10x_audio_startup,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1513,21 +1607,23 @@ static const struct snd_soc_dai_ops ac10x_aif1_dai_ops = {
|
||||||
static struct snd_soc_dai_driver ac10x_dai[] = {
|
static struct snd_soc_dai_driver ac10x_dai[] = {
|
||||||
{
|
{
|
||||||
.name = "ac10x-aif1",
|
.name = "ac10x-aif1",
|
||||||
.id = 1,
|
.id = AIF1_CLK,
|
||||||
.playback = {
|
.playback = {
|
||||||
.stream_name = "AIF1 Playback",
|
.stream_name = "AIF1 Playback",
|
||||||
.channels_min = 1,
|
.channels_min = 1,
|
||||||
.channels_max = 2,
|
.channels_max = 8,
|
||||||
.rates = ac10x_RATES,
|
.rates = ac10x_RATES,
|
||||||
.formats = ac10x_FORMATS,
|
.formats = ac10x_FORMATS,
|
||||||
},
|
},
|
||||||
|
#if 0
|
||||||
.capture = {
|
.capture = {
|
||||||
.stream_name = "AIF1 Capture",
|
.stream_name = "AIF1 Capture",
|
||||||
.channels_min = 1,
|
.channels_min = 1,
|
||||||
.channels_max = 2,
|
.channels_max = 8,
|
||||||
.rates = ac10x_RATES,
|
.rates = ac10x_RATES,
|
||||||
.formats = ac10x_FORMATS,
|
.formats = ac10x_FORMATS,
|
||||||
},
|
},
|
||||||
|
#endif
|
||||||
.ops = &ac10x_aif1_dai_ops,
|
.ops = &ac10x_aif1_dai_ops,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1754,7 +1850,10 @@ static void codec_resume_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct ac10x_priv *ac10x = container_of(work, struct ac10x_priv, codec_resume);
|
struct ac10x_priv *ac10x = container_of(work, struct ac10x_priv, codec_resume);
|
||||||
struct snd_soc_codec *codec = ac10x->codec;
|
struct snd_soc_codec *codec = ac10x->codec;
|
||||||
int i ,ret =0;
|
int i, ret = 0;
|
||||||
|
|
||||||
|
AC10X_DBG("%s() L%d +++\n", __func__, __LINE__);
|
||||||
|
|
||||||
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
||||||
ac10x->virq = gpio_to_irq(SWITCH_DETECT);
|
ac10x->virq = gpio_to_irq(SWITCH_DETECT);
|
||||||
if (IS_ERR_VALUE(ac10x->virq)) {
|
if (IS_ERR_VALUE(ac10x->virq)) {
|
||||||
|
@ -1785,9 +1884,10 @@ static void codec_resume_work(struct work_struct *work)
|
||||||
}
|
}
|
||||||
/*enable this bit to prevent leakage from ldoin*/
|
/*enable this bit to prevent leakage from ldoin*/
|
||||||
snd_soc_update_bits(codec, ADDA_TUNE3, (0x1<<OSCEN), (0x1<<OSCEN));
|
snd_soc_update_bits(codec, ADDA_TUNE3, (0x1<<OSCEN), (0x1<<OSCEN));
|
||||||
|
|
||||||
|
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
||||||
gpio_direction_output(PA_CTL, 1);
|
gpio_direction_output(PA_CTL, 1);
|
||||||
gpio_set_value(PA_CTL, 0);
|
gpio_set_value(PA_CTL, 0);
|
||||||
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
|
||||||
msleep(200);
|
msleep(200);
|
||||||
ret = snd_soc_read(codec, HMIC_STS);
|
ret = snd_soc_read(codec, HMIC_STS);
|
||||||
ret = (ret>>HMIC_DATA);
|
ret = (ret>>HMIC_DATA);
|
||||||
|
@ -1797,6 +1897,9 @@ static void codec_resume_work(struct work_struct *work)
|
||||||
switch_status_update(ac10x);
|
switch_status_update(ac10x);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
AC10X_DBG("%s() L%d +++\n", __func__, __LINE__);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1853,22 +1956,29 @@ static struct attribute_group audio_debug_attr_group = {
|
||||||
.attrs = audio_debug_attrs,
|
.attrs = audio_debug_attrs,
|
||||||
};
|
};
|
||||||
/************************************************************/
|
/************************************************************/
|
||||||
|
static const struct regmap_config ac101_regmap = {
|
||||||
|
.reg_bits = 8,
|
||||||
|
.val_bits = 16,
|
||||||
|
.reg_stride = 1,
|
||||||
|
|
||||||
|
.max_register = 0xB5,
|
||||||
|
.cache_type = REGCACHE_RBTREE,
|
||||||
|
};
|
||||||
|
|
||||||
static int ac10x_codec_probe(struct snd_soc_codec *codec)
|
static int ac10x_codec_probe(struct snd_soc_codec *codec)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
struct ac10x_priv *ac10x;
|
struct ac10x_priv *ac10x;
|
||||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
|
||||||
ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
|
|
||||||
if (ret < 0) {
|
|
||||||
printk(KERN_ERR "ac10x: failed to set cache I/O: %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
ac10x = dev_get_drvdata(codec->dev);
|
ac10x = dev_get_drvdata(codec->dev);
|
||||||
if (ac10x == NULL) {
|
if (ac10x == NULL) {
|
||||||
|
AC10X_DBG("not set client data %s() L%d\n", __func__, __LINE__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
ac10x->codec = codec;
|
ac10x->codec = codec;
|
||||||
|
|
||||||
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
||||||
ac10x->sdev.state = 0;
|
ac10x->sdev.state = 0;
|
||||||
ac10x->state = -1;
|
ac10x->state = -1;
|
||||||
|
@ -1934,6 +2044,7 @@ static int ac10x_codec_probe(struct snd_soc_codec *codec)
|
||||||
mutex_init(&ac10x->adc_mutex);
|
mutex_init(&ac10x->adc_mutex);
|
||||||
mutex_init(&ac10x->aifclk_mutex);
|
mutex_init(&ac10x->aifclk_mutex);
|
||||||
|
|
||||||
|
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
||||||
/*request pa gpio*/
|
/*request pa gpio*/
|
||||||
ret = gpio_request(PA_CTL, NULL);
|
ret = gpio_request(PA_CTL, NULL);
|
||||||
if (0 != ret) {
|
if (0 != ret) {
|
||||||
|
@ -1946,7 +2057,6 @@ static int ac10x_codec_probe(struct snd_soc_codec *codec)
|
||||||
gpio_set_value(PA_CTL, 0);
|
gpio_set_value(PA_CTL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
|
||||||
ac10x->virq = gpio_to_irq(SWITCH_DETECT);
|
ac10x->virq = gpio_to_irq(SWITCH_DETECT);
|
||||||
if (IS_ERR_VALUE(ac10x->virq)) {
|
if (IS_ERR_VALUE(ac10x->virq)) {
|
||||||
pr_err("[ac10x] map gpio to virq failed, errno = %d\n",ac10x->virq);
|
pr_err("[ac10x] map gpio to virq failed, errno = %d\n",ac10x->virq);
|
||||||
|
@ -1968,8 +2078,7 @@ static int ac10x_codec_probe(struct snd_soc_codec *codec)
|
||||||
for (i = 0; i < ARRAY_SIZE(ac10x_supplies); i++)
|
for (i = 0; i < ARRAY_SIZE(ac10x_supplies); i++)
|
||||||
ac10x->supplies[i].supply = ac10x_supplies[i];
|
ac10x->supplies[i].supply = ac10x_supplies[i];
|
||||||
|
|
||||||
ret = regulator_bulk_get(NULL, ac10x->num_supplies,
|
ret = regulator_bulk_get(NULL, ac10x->num_supplies, ac10x->supplies);
|
||||||
ac10x->supplies);
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
pr_err("[ac10x] Failed to get supplies: %d\n", ret);
|
pr_err("[ac10x] Failed to get supplies: %d\n", ret);
|
||||||
}
|
}
|
||||||
|
@ -1997,6 +2106,7 @@ static int ac10x_codec_probe(struct snd_soc_codec *codec)
|
||||||
snd_soc_dapm_new_controls(dapm, ac10x_dapm_widgets, ARRAY_SIZE(ac10x_dapm_widgets));
|
snd_soc_dapm_new_controls(dapm, ac10x_dapm_widgets, ARRAY_SIZE(ac10x_dapm_widgets));
|
||||||
snd_soc_dapm_add_routes(dapm, ac10x_dapm_routes, ARRAY_SIZE(ac10x_dapm_routes));
|
snd_soc_dapm_add_routes(dapm, ac10x_dapm_routes, ARRAY_SIZE(ac10x_dapm_routes));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
||||||
err_switch_work_queue:
|
err_switch_work_queue:
|
||||||
devm_free_irq(codec->dev,ac10x->virq,NULL);
|
devm_free_irq(codec->dev,ac10x->virq,NULL);
|
||||||
|
@ -2010,7 +2120,6 @@ err_input_allocate_device:
|
||||||
switch_dev_unregister(&ac10x->sdev);
|
switch_dev_unregister(&ac10x->sdev);
|
||||||
|
|
||||||
err_switch_dev_register:
|
err_switch_dev_register:
|
||||||
kfree(ac10x);
|
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -2019,16 +2128,17 @@ err_switch_dev_register:
|
||||||
static int ac10x_codec_remove(struct snd_soc_codec *codec)
|
static int ac10x_codec_remove(struct snd_soc_codec *codec)
|
||||||
{
|
{
|
||||||
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
struct device *dev = codec->dev;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
devm_free_irq(dev,ac10x->virq,NULL);
|
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
||||||
|
devm_free_irq(codec->dev,ac10x->virq,NULL);
|
||||||
if (ac10x->key) {
|
if (ac10x->key) {
|
||||||
input_unregister_device(ac10x->key);
|
input_unregister_device(ac10x->key);
|
||||||
input_free_device(ac10x->key);
|
input_free_device(ac10x->key);
|
||||||
}
|
}
|
||||||
switch_dev_unregister(&ac10x->sdev);
|
switch_dev_unregister(&ac10x->sdev);
|
||||||
|
#endif
|
||||||
for (i = 0; i < ARRAY_SIZE(ac10x_supplies); i++){
|
for (i = 0; i < ARRAY_SIZE(ac10x_supplies); i++){
|
||||||
ret = regulator_disable(ac10x->supplies[i].consumer);
|
ret = regulator_disable(ac10x->supplies[i].consumer);
|
||||||
|
|
||||||
|
@ -2038,7 +2148,6 @@ static int ac10x_codec_remove(struct snd_soc_codec *codec)
|
||||||
regulator_put(ac10x->supplies[i].consumer);
|
regulator_put(ac10x->supplies[i].consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(ac10x);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2046,6 +2155,7 @@ static int ac10x_codec_suspend(struct snd_soc_codec *codec)
|
||||||
{
|
{
|
||||||
int i ,ret =0;
|
int i ,ret =0;
|
||||||
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
|
|
||||||
AC10X_DBG("[codec]:suspend\n");
|
AC10X_DBG("[codec]:suspend\n");
|
||||||
ac10x_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
ac10x_set_bias_level(codec, SND_SOC_BIAS_OFF);
|
||||||
for (i = 0; i < ARRAY_SIZE(ac10x_supplies); i++){
|
for (i = 0; i < ARRAY_SIZE(ac10x_supplies); i++){
|
||||||
|
@ -2056,18 +2166,33 @@ static int ac10x_codec_suspend(struct snd_soc_codec *codec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regcache_cache_only(ac10x->regmap, true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ac10x_codec_resume(struct snd_soc_codec *codec)
|
static int ac10x_codec_resume(struct snd_soc_codec *codec)
|
||||||
{
|
{
|
||||||
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
|
int ret;
|
||||||
|
|
||||||
AC10X_DBG("[codec]:resume");
|
AC10X_DBG("[codec]:resume");
|
||||||
|
|
||||||
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
#ifndef CONFIG_SWITCH_DETECT_EXTERNAL
|
||||||
ac10x->mode = HEADPHONE_IDLE;
|
ac10x->mode = HEADPHONE_IDLE;
|
||||||
headphone_state = 0;
|
headphone_state = 0;
|
||||||
ac10x->state = -1;
|
ac10x->state = -1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Sync reg_cache with the hardware */
|
||||||
|
regcache_cache_only(ac10x->regmap, false);
|
||||||
|
ret = regcache_sync(ac10x->regmap);
|
||||||
|
if (ret != 0) {
|
||||||
|
dev_err(codec->dev, "Failed to sync register cache: %d\n", ret);
|
||||||
|
regcache_cache_only(ac10x->regmap, true);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ac10x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
ac10x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
|
||||||
schedule_work(&ac10x->codec_resume);
|
schedule_work(&ac10x->codec_resume);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2081,21 +2206,45 @@ static struct snd_soc_codec_driver soc_codec_dev_sndvir_audio = {
|
||||||
.ignore_pmdown_time = 1,
|
.ignore_pmdown_time = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __devinit ac10x_probe(struct i2c_client *i2c,
|
static int ac10x_probe(struct i2c_client *i2c,
|
||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct ac10x_priv *ac10x;
|
struct ac10x_priv *ac10x;
|
||||||
|
unsigned v;
|
||||||
|
|
||||||
AC10X_DBG("%s,line:%d\n", __func__, __LINE__);
|
AC10X_DBG("%s,line:%d\n", __func__, __LINE__);
|
||||||
ac10x = devm_kzalloc(&i2c->dev, sizeof(struct ac10x_priv), GFP_KERNEL);
|
ac10x = devm_kzalloc(&i2c->dev, sizeof(struct ac10x_priv), GFP_KERNEL);
|
||||||
if (ac10x == NULL) {
|
if (ac10x == NULL) {
|
||||||
|
AC10X_DBG("no memory %s() L%d\n", __func__, __LINE__);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
i2c_set_clientdata(i2c, ac10x);
|
i2c_set_clientdata(i2c, ac10x);
|
||||||
|
|
||||||
|
ac10x->regmap = devm_regmap_init_i2c(i2c, &ac101_regmap);
|
||||||
|
if (IS_ERR(ac10x->regmap)) {
|
||||||
|
ret = PTR_ERR(ac10x->regmap);
|
||||||
|
dev_err(&i2c->dev, "Fail to initialize I/O: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regmap_read(ac10x->regmap, CHIP_AUDIO_RST, &v);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(&i2c->dev, "failed to read vendor ID: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v != AC101_CHIP_ID) {
|
||||||
|
dev_err(&i2c->dev, "chip is not AC101\n");
|
||||||
|
dev_err(&i2c->dev, "Expected %X\n", AC101_CHIP_ID);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_sndvir_audio, ac10x_dai, ARRAY_SIZE(ac10x_dai));
|
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_sndvir_audio, ac10x_dai, ARRAY_SIZE(ac10x_dai));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&i2c->dev, "Failed to register ac10x: %d\n", ret);
|
dev_err(&i2c->dev, "Failed to register ac10x: %d\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = sysfs_create_group(&i2c->dev.kobj, &audio_debug_attr_group);
|
ret = sysfs_create_group(&i2c->dev.kobj, &audio_debug_attr_group);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("failed to create attr group\n");
|
pr_err("failed to create attr group\n");
|
||||||
|
@ -2133,26 +2282,36 @@ static void ac10x_shutdown(struct i2c_client *i2c)
|
||||||
reg_val &= ~((0x1<<RHPPA_MUTE)|(0x1<<LHPPA_MUTE));
|
reg_val &= ~((0x1<<RHPPA_MUTE)|(0x1<<LHPPA_MUTE));
|
||||||
snd_soc_write(codec, HPOUT_CTRL, reg_val);
|
snd_soc_write(codec, HPOUT_CTRL, reg_val);
|
||||||
|
|
||||||
|
#if PA_CTL
|
||||||
/*disable pa_ctrl*/
|
/*disable pa_ctrl*/
|
||||||
gpio_set_value(PA_CTL, 0);
|
gpio_set_value(PA_CTL, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
static int __devexit ac10x_remove(struct i2c_client *i2c)
|
static int ac10x_remove(struct i2c_client *i2c)
|
||||||
{
|
{
|
||||||
|
struct ac10x_priv *ac10x = i2c_get_clientdata(i2c);
|
||||||
sysfs_remove_group(&i2c->dev.kobj, &audio_debug_attr_group);
|
sysfs_remove_group(&i2c->dev.kobj, &audio_debug_attr_group);
|
||||||
snd_soc_unregister_codec(&i2c->dev);
|
snd_soc_unregister_codec(&i2c->dev);
|
||||||
|
if (ac10x) {
|
||||||
|
kfree(ac10x);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ac10x_driver_detect(struct i2c_client *client, struct i2c_board_info *info)
|
int ac10x_driver_detect(struct i2c_client *client, struct i2c_board_info *info)
|
||||||
{
|
{
|
||||||
struct i2c_adapter *adapter = client->adapter;
|
struct i2c_adapter *adapter = client->adapter;
|
||||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
|
||||||
|
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
|
||||||
|
AC10X_DBG("no device found %s() L%d\n", __func__, __LINE__);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
}
|
||||||
if (I2C_BUS == adapter->nr) {
|
if (I2C_BUS == adapter->nr) {
|
||||||
strlcpy(info->type, "ac10x-codec", I2C_NAME_SIZE);
|
strlcpy(info->type, "ac10x-codec", I2C_NAME_SIZE);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
AC10X_DBG("no device found %s() L%d\n", __func__, __LINE__);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2161,14 +2320,21 @@ static const struct i2c_device_id ac10x_id[] = {
|
||||||
{"ac10x-codec", 0},
|
{"ac10x-codec", 0},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
static const struct of_device_id ac101_of_match[] = {
|
||||||
|
{ .compatible = "x-power,ac101", },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, ac101_of_match);
|
||||||
|
|
||||||
static struct i2c_driver ac10x_codec_driver = {
|
static struct i2c_driver ac10x_codec_driver = {
|
||||||
.class = I2C_CLASS_HWMON,
|
.class = I2C_CLASS_HWMON,
|
||||||
.id_table = ac10x_id,
|
.id_table = ac10x_id,
|
||||||
.probe = ac10x_probe,
|
.probe = ac10x_probe,
|
||||||
.remove = __devexit_p(ac10x_remove),
|
.remove = ac10x_remove,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "ac10x-codec",
|
.name = "ac10x-codec",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = ac101_of_match,
|
||||||
},
|
},
|
||||||
.address_list = normal_i2c,
|
.address_list = normal_i2c,
|
||||||
.detect = ac10x_driver_detect,
|
.detect = ac10x_driver_detect,
|
||||||
|
|
5
ac101.h
5
ac101.h
|
@ -71,6 +71,9 @@
|
||||||
#define ADDA_TUNE3 0x5c
|
#define ADDA_TUNE3 0x5c
|
||||||
#define HPOUT_STR 0x5d
|
#define HPOUT_STR 0x5d
|
||||||
|
|
||||||
|
/*CHIP_AUDIO_RST*/
|
||||||
|
#define AC101_CHIP_ID 0x0101
|
||||||
|
|
||||||
/*PLL_CTRL1*/
|
/*PLL_CTRL1*/
|
||||||
#define DPLL_DAC_BIAS 14
|
#define DPLL_DAC_BIAS 14
|
||||||
#define PLL_POSTDIV_M 8
|
#define PLL_POSTDIV_M 8
|
||||||
|
@ -423,7 +426,7 @@ struct spk_gpio {
|
||||||
};
|
};
|
||||||
#define AC10X_DEBG
|
#define AC10X_DEBG
|
||||||
#ifdef AC10X_DEBG
|
#ifdef AC10X_DEBG
|
||||||
#define AC10X_DBG(format,args...) printk("[AC100] "format,##args)
|
#define AC10X_DBG(format,args...) printk("[AC101] "format,##args)
|
||||||
#else
|
#else
|
||||||
#define AC10X_DBG(...)
|
#define AC10X_DBG(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,6 +30,12 @@
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
|
ac101: ac101@1a{
|
||||||
|
compatible = "x-power,ac101";
|
||||||
|
reg = <0x1a>;
|
||||||
|
#sound-dai-cells = <0>;
|
||||||
|
};
|
||||||
|
/*
|
||||||
ac108_a: ac108@35{
|
ac108_a: ac108@35{
|
||||||
compatible = "x-power,ac108_0";
|
compatible = "x-power,ac108_0";
|
||||||
reg = <0x35>;
|
reg = <0x35>;
|
||||||
|
@ -43,10 +49,10 @@
|
||||||
#sound-dai-cells = <0>;
|
#sound-dai-cells = <0>;
|
||||||
data-protocol = <0>;
|
data-protocol = <0>;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
fragment@3 {
|
fragment@3 {
|
||||||
target = <&sound>;
|
target = <&sound>;
|
||||||
|
|
||||||
|
@ -64,13 +70,14 @@
|
||||||
cpu_dai: simple-audio-card,cpu {
|
cpu_dai: simple-audio-card,cpu {
|
||||||
sound-dai = <&i2s>;
|
sound-dai = <&i2s>;
|
||||||
dai-tdm-slot-num = <2>;
|
dai-tdm-slot-num = <2>;
|
||||||
dai-tdm-slot-width = <32>;
|
dai-tdm-slot-width = <16>;
|
||||||
dai-tdm-slot-tx-mask = <1 1 0 0>;
|
dai-tdm-slot-tx-mask = <1 1 0 0>;
|
||||||
dai-tdm-slot-rx-mask = <1 1 0 0>;
|
dai-tdm-slot-rx-mask = <1 1 0 0>;
|
||||||
};
|
};
|
||||||
codec_dai: simple-audio-card,codec {
|
codec_dai: simple-audio-card,codec {
|
||||||
sound-dai = <&ac108_b>;
|
sound-dai = <&ac101>;
|
||||||
clocks = <&ac108_mclk>;
|
clocks = <&ac108_mclk>;
|
||||||
|
system-clock-id = <1>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
Binary file not shown.
Loading…
Reference in a new issue