Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
7cf143ca
Commit
7cf143ca
authored
Jan 26, 2018
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branches 'asoc/topic/nau8825' and 'asoc/topic/nuc900' into asoc-next
parents
19c2d849
fa25b4f5
65a12b3a
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
73 additions
and
46 deletions
+73
-46
Documentation/devicetree/bindings/sound/nau8825.txt
Documentation/devicetree/bindings/sound/nau8825.txt
+2
-2
sound/soc/codecs/nau8825.c
sound/soc/codecs/nau8825.c
+64
-37
sound/soc/codecs/nau8825.h
sound/soc/codecs/nau8825.h
+2
-1
sound/soc/nuc900/nuc900-ac97.c
sound/soc/nuc900/nuc900-ac97.c
+5
-6
No files found.
Documentation/devicetree/bindings/sound/nau8825.txt
View file @
7cf143ca
...
...
@@ -69,7 +69,7 @@ Optional properties:
- nuvoton,jack-insert-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
- nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms
- nuvoton,crosstalk-
bypass: make crosstalk function bypass
if set.
- nuvoton,crosstalk-
enable: make crosstalk function enable
if set.
- clocks: list of phandle and clock specifier pairs according to common clock bindings for the
clocks described in clock-names
...
...
@@ -98,7 +98,7 @@ Example:
nuvoton,short-key-debounce = <2>;
nuvoton,jack-insert-debounce = <7>;
nuvoton,jack-eject-debounce = <7>;
nuvoton,crosstalk-
bypass
;
nuvoton,crosstalk-
enable
;
clock-names = "mclk";
clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_2>;
...
...
sound/soc/codecs/nau8825.c
View file @
7cf143ca
...
...
@@ -194,10 +194,10 @@ static const struct reg_default nau8825_reg_defaults[] = {
/* register backup table when cross talk detection */
static
struct
reg_default
nau8825_xtalk_baktab
[]
=
{
{
NAU8825_REG_ADC_DGAIN_CTRL
,
0
},
{
NAU8825_REG_ADC_DGAIN_CTRL
,
0
x00cf
},
{
NAU8825_REG_HSVOL_CTRL
,
0
},
{
NAU8825_REG_DACL_CTRL
,
0
},
{
NAU8825_REG_DACR_CTRL
,
0
},
{
NAU8825_REG_DACL_CTRL
,
0
x00cf
},
{
NAU8825_REG_DACR_CTRL
,
0
x02cf
},
};
static
const
unsigned
short
logtable
[
256
]
=
{
...
...
@@ -245,13 +245,14 @@ static const unsigned short logtable[256] = {
* tasks are allowed to acquire the semaphore, calling this function will
* put the task to sleep. If the semaphore is not released within the
* specified number of jiffies, this function returns.
* Acquires the semaphore without jiffies. If no more tasks are allowed
* to acquire the semaphore, calling this function will put the task to
* sleep until the semaphore is released.
* If the semaphore is not released within the specified number of jiffies,
* this function returns -ETIME.
* If the sleep is interrupted by a signal, this function will return -EINTR.
* It returns 0 if the semaphore was acquired successfully.
* this function returns -ETIME. If the sleep is interrupted by a signal,
* this function will return -EINTR. It returns 0 if the semaphore was
* acquired successfully.
*
* Acquires the semaphore without jiffies. Try to acquire the semaphore
* atomically. Returns 0 if the semaphore has been acquired successfully
* or 1 if it it cannot be acquired.
*/
static
int
nau8825_sema_acquire
(
struct
nau8825
*
nau8825
,
long
timeout
)
{
...
...
@@ -262,8 +263,8 @@ static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout)
if
(
ret
<
0
)
dev_warn
(
nau8825
->
dev
,
"Acquire semaphore timeout
\n
"
);
}
else
{
ret
=
down_
interruptible
(
&
nau8825
->
xtalk_sem
);
if
(
ret
<
0
)
ret
=
down_
trylock
(
&
nau8825
->
xtalk_sem
);
if
(
ret
)
dev_warn
(
nau8825
->
dev
,
"Acquire semaphore fail
\n
"
);
}
...
...
@@ -454,22 +455,32 @@ static void nau8825_xtalk_backup(struct nau8825 *nau8825)
{
int
i
;
if
(
nau8825
->
xtalk_baktab_initialized
)
return
;
/* Backup some register values to backup table */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
nau8825_xtalk_baktab
);
i
++
)
regmap_read
(
nau8825
->
regmap
,
nau8825_xtalk_baktab
[
i
].
reg
,
&
nau8825_xtalk_baktab
[
i
].
def
);
nau8825
->
xtalk_baktab_initialized
=
true
;
}
static
void
nau8825_xtalk_restore
(
struct
nau8825
*
nau8825
)
static
void
nau8825_xtalk_restore
(
struct
nau8825
*
nau8825
,
bool
cause_cancel
)
{
int
i
,
volume
;
if
(
!
nau8825
->
xtalk_baktab_initialized
)
return
;
/* Restore register values from backup table; When the driver restores
* the headphone volumem, it needs recover to original level gradually
* with 3dB per step for less pop noise.
* the headphone volume in XTALK_DONE state, it needs recover to
* original level gradually with 3dB per step for less pop noise.
* Otherwise, the restore should do ASAP.
*/
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
nau8825_xtalk_baktab
);
i
++
)
{
if
(
nau8825_xtalk_baktab
[
i
].
reg
==
NAU8825_REG_HSVOL_CTRL
)
{
if
(
!
cause_cancel
&&
nau8825_xtalk_baktab
[
i
].
reg
==
NAU8825_REG_HSVOL_CTRL
)
{
/* Ramping up the volume change to reduce pop noise */
volume
=
nau8825_xtalk_baktab
[
i
].
def
&
NAU8825_HPR_VOL_MASK
;
...
...
@@ -479,6 +490,8 @@ static void nau8825_xtalk_restore(struct nau8825 *nau8825)
regmap_write
(
nau8825
->
regmap
,
nau8825_xtalk_baktab
[
i
].
reg
,
nau8825_xtalk_baktab
[
i
].
def
);
}
nau8825
->
xtalk_baktab_initialized
=
false
;
}
static
void
nau8825_xtalk_prepare_dac
(
struct
nau8825
*
nau8825
)
...
...
@@ -644,7 +657,7 @@ static void nau8825_xtalk_clean_adc(struct nau8825 *nau8825)
NAU8825_POWERUP_ADCL
|
NAU8825_ADC_VREFSEL_MASK
,
0
);
}
static
void
nau8825_xtalk_clean
(
struct
nau8825
*
nau8825
)
static
void
nau8825_xtalk_clean
(
struct
nau8825
*
nau8825
,
bool
cause_cancel
)
{
/* Enable internal VCO needed for interruptions */
nau8825_configure_sysclk
(
nau8825
,
NAU8825_CLK_INTERNAL
,
0
);
...
...
@@ -660,7 +673,7 @@ static void nau8825_xtalk_clean(struct nau8825 *nau8825)
NAU8825_I2S_MS_MASK
|
NAU8825_I2S_LRC_DIV_MASK
|
NAU8825_I2S_BLK_DIV_MASK
,
NAU8825_I2S_MS_SLAVE
);
/* Restore value of specific register for cross talk */
nau8825_xtalk_restore
(
nau8825
);
nau8825_xtalk_restore
(
nau8825
,
cause_cancel
);
}
static
void
nau8825_xtalk_imm_start
(
struct
nau8825
*
nau8825
,
int
vol
)
...
...
@@ -779,7 +792,7 @@ static void nau8825_xtalk_measure(struct nau8825 *nau8825)
dev_dbg
(
nau8825
->
dev
,
"cross talk sidetone: %x
\n
"
,
sidetone
);
regmap_write
(
nau8825
->
regmap
,
NAU8825_REG_DAC_DGAIN_CTRL
,
(
sidetone
<<
8
)
|
sidetone
);
nau8825_xtalk_clean
(
nau8825
);
nau8825_xtalk_clean
(
nau8825
,
false
);
nau8825
->
xtalk_state
=
NAU8825_XTALK_DONE
;
break
;
default:
...
...
@@ -815,13 +828,14 @@ static void nau8825_xtalk_work(struct work_struct *work)
static
void
nau8825_xtalk_cancel
(
struct
nau8825
*
nau8825
)
{
/* If the
xtalk_protect is true, that means the process is still
*
on going. The driver forces to cancel the cross
talk task and
/* If the
crosstalk is eanbled and the process is on going,
*
the driver forces to cancel the cross
talk task and
* restores the configuration to original status.
*/
if
(
nau8825
->
xtalk_protect
)
{
if
(
nau8825
->
xtalk_enable
&&
nau8825
->
xtalk_state
!=
NAU8825_XTALK_DONE
)
{
cancel_work_sync
(
&
nau8825
->
xtalk_work
);
nau8825_xtalk_clean
(
nau8825
);
nau8825_xtalk_clean
(
nau8825
,
true
);
}
/* Reset parameters for cross talk suppression function */
nau8825_sema_reset
(
nau8825
);
...
...
@@ -1246,8 +1260,10 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
regmap_read
(
nau8825
->
regmap
,
NAU8825_REG_DAC_CTRL1
,
&
osr
);
osr
&=
NAU8825_DAC_OVERSAMPLE_MASK
;
if
(
nau8825_clock_check
(
nau8825
,
substream
->
stream
,
params_rate
(
params
),
osr
))
params_rate
(
params
),
osr
))
{
nau8825_sema_release
(
nau8825
);
return
-
EINVAL
;
}
regmap_update_bits
(
nau8825
->
regmap
,
NAU8825_REG_CLK_DIVIDER
,
NAU8825_CLK_DAC_SRC_MASK
,
osr_dac_sel
[
osr
].
clk_src
<<
NAU8825_CLK_DAC_SRC_SFT
);
...
...
@@ -1255,8 +1271,10 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
regmap_read
(
nau8825
->
regmap
,
NAU8825_REG_ADC_RATE
,
&
osr
);
osr
&=
NAU8825_ADC_SYNC_DOWN_MASK
;
if
(
nau8825_clock_check
(
nau8825
,
substream
->
stream
,
params_rate
(
params
),
osr
))
params_rate
(
params
),
osr
))
{
nau8825_sema_release
(
nau8825
);
return
-
EINVAL
;
}
regmap_update_bits
(
nau8825
->
regmap
,
NAU8825_REG_CLK_DIVIDER
,
NAU8825_CLK_ADC_SRC_MASK
,
osr_adc_sel
[
osr
].
clk_src
<<
NAU8825_CLK_ADC_SRC_SFT
);
...
...
@@ -1273,8 +1291,10 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
bclk_div
=
1
;
else
if
(
bclk_fs
<=
128
)
bclk_div
=
0
;
else
else
{
nau8825_sema_release
(
nau8825
);
return
-
EINVAL
;
}
regmap_update_bits
(
nau8825
->
regmap
,
NAU8825_REG_I2S_PCM_CTRL2
,
NAU8825_I2S_LRC_DIV_MASK
|
NAU8825_I2S_BLK_DIV_MASK
,
((
bclk_div
+
1
)
<<
NAU8825_I2S_LRC_DIV_SFT
)
|
bclk_div
);
...
...
@@ -1294,6 +1314,7 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
val_len
|=
NAU8825_I2S_DL_32
;
break
;
default:
nau8825_sema_release
(
nau8825
);
return
-
EINVAL
;
}
...
...
@@ -1312,8 +1333,6 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
struct
nau8825
*
nau8825
=
snd_soc_codec_get_drvdata
(
codec
);
unsigned
int
ctrl1_val
=
0
,
ctrl2_val
=
0
;
nau8825_sema_acquire
(
nau8825
,
3
*
HZ
);
switch
(
fmt
&
SND_SOC_DAIFMT_MASTER_MASK
)
{
case
SND_SOC_DAIFMT_CBM_CFM
:
ctrl2_val
|=
NAU8825_I2S_MS_MASTER
;
...
...
@@ -1355,6 +1374,8 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
return
-
EINVAL
;
}
nau8825_sema_acquire
(
nau8825
,
3
*
HZ
);
regmap_update_bits
(
nau8825
->
regmap
,
NAU8825_REG_I2S_PCM_CTRL1
,
NAU8825_I2S_DL_MASK
|
NAU8825_I2S_DF_MASK
|
NAU8825_I2S_BP_MASK
|
NAU8825_I2S_PCMB_MASK
,
...
...
@@ -1687,7 +1708,7 @@ static irqreturn_t nau8825_interrupt(int irq, void *data)
}
else
if
(
active_irq
&
NAU8825_HEADSET_COMPLETION_IRQ
)
{
if
(
nau8825_is_jack_inserted
(
regmap
))
{
event
|=
nau8825_jack_insert
(
nau8825
);
if
(
!
nau8825
->
xtalk_bypass
&&
!
nau8825
->
high_imped
)
{
if
(
nau8825
->
xtalk_enable
&&
!
nau8825
->
high_imped
)
{
/* Apply the cross talk suppression in the
* headset without high impedance.
*/
...
...
@@ -1701,12 +1722,15 @@ static irqreturn_t nau8825_interrupt(int irq, void *data)
int
ret
;
nau8825
->
xtalk_protect
=
true
;
ret
=
nau8825_sema_acquire
(
nau8825
,
0
);
if
(
ret
<
0
)
if
(
ret
)
nau8825
->
xtalk_protect
=
false
;
}
/* Startup cross talk detection process */
nau8825
->
xtalk_state
=
NAU8825_XTALK_PREPARE
;
schedule_work
(
&
nau8825
->
xtalk_work
);
if
(
nau8825
->
xtalk_protect
)
{
nau8825
->
xtalk_state
=
NAU8825_XTALK_PREPARE
;
schedule_work
(
&
nau8825
->
xtalk_work
);
}
}
else
{
/* The cross talk suppression shouldn't apply
* in the headset with high impedance. Thus,
...
...
@@ -1733,7 +1757,9 @@ static irqreturn_t nau8825_interrupt(int irq, void *data)
nau8825
->
xtalk_event_mask
=
event_mask
;
}
}
else
if
(
active_irq
&
NAU8825_IMPEDANCE_MEAS_IRQ
)
{
schedule_work
(
&
nau8825
->
xtalk_work
);
/* crosstalk detection enable and process on going */
if
(
nau8825
->
xtalk_enable
&&
nau8825
->
xtalk_protect
)
schedule_work
(
&
nau8825
->
xtalk_work
);
clear_irq
=
NAU8825_IMPEDANCE_MEAS_IRQ
;
}
else
if
((
active_irq
&
NAU8825_JACK_INSERTION_IRQ_MASK
)
==
NAU8825_JACK_INSERTION_DETECTED
)
{
...
...
@@ -2382,7 +2408,7 @@ static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
regcache_sync
(
nau8825
->
regmap
);
nau8825
->
xtalk_protect
=
true
;
ret
=
nau8825_sema_acquire
(
nau8825
,
0
);
if
(
ret
<
0
)
if
(
ret
)
nau8825
->
xtalk_protect
=
false
;
enable_irq
(
nau8825
->
irq
);
...
...
@@ -2441,8 +2467,8 @@ static void nau8825_print_device_properties(struct nau8825 *nau8825)
nau8825
->
jack_insert_debounce
);
dev_dbg
(
dev
,
"jack-eject-debounce: %d
\n
"
,
nau8825
->
jack_eject_debounce
);
dev_dbg
(
dev
,
"crosstalk-
bypass
: %d
\n
"
,
nau8825
->
xtalk_
bypass
);
dev_dbg
(
dev
,
"crosstalk-
enable
: %d
\n
"
,
nau8825
->
xtalk_
enable
);
}
static
int
nau8825_read_device_properties
(
struct
device
*
dev
,
...
...
@@ -2507,8 +2533,8 @@ static int nau8825_read_device_properties(struct device *dev,
&
nau8825
->
jack_eject_debounce
);
if
(
ret
)
nau8825
->
jack_eject_debounce
=
0
;
nau8825
->
xtalk_
bypass
=
device_property_read_bool
(
dev
,
"nuvoton,crosstalk-
bypass
"
);
nau8825
->
xtalk_
enable
=
device_property_read_bool
(
dev
,
"nuvoton,crosstalk-
enable
"
);
nau8825
->
mclk
=
devm_clk_get
(
dev
,
"mclk"
);
if
(
PTR_ERR
(
nau8825
->
mclk
)
==
-
EPROBE_DEFER
)
{
...
...
@@ -2569,6 +2595,7 @@ static int nau8825_i2c_probe(struct i2c_client *i2c,
*/
nau8825
->
xtalk_state
=
NAU8825_XTALK_DONE
;
nau8825
->
xtalk_protect
=
false
;
nau8825
->
xtalk_baktab_initialized
=
false
;
sema_init
(
&
nau8825
->
xtalk_sem
,
1
);
INIT_WORK
(
&
nau8825
->
xtalk_work
,
nau8825_xtalk_work
);
...
...
sound/soc/codecs/nau8825.h
View file @
7cf143ca
...
...
@@ -476,7 +476,8 @@ struct nau8825 {
int
xtalk_event_mask
;
bool
xtalk_protect
;
int
imp_rms
[
NAU8825_XTALK_IMM
];
int
xtalk_bypass
;
int
xtalk_enable
;
bool
xtalk_baktab_initialized
;
/* True if initialized. */
};
int
nau8825_enable_jack_detect
(
struct
snd_soc_codec
*
codec
,
...
...
sound/soc/nuc900/nuc900-ac97.c
View file @
7cf143ca
...
...
@@ -67,7 +67,7 @@ static unsigned short nuc900_ac97_read(struct snd_ac97 *ac97,
/* polling the AC_R_FINISH */
while
(
!
(
AUDIO_READ
(
nuc900_audio
->
mmio
+
ACTL_ACCON
)
&
AC_R_FINISH
)
&&
timeout
--
)
&&
--
timeout
)
mdelay
(
1
);
if
(
!
timeout
)
{
...
...
@@ -121,7 +121,7 @@ static void nuc900_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
/* polling the AC_W_FINISH */
while
((
AUDIO_READ
(
nuc900_audio
->
mmio
+
ACTL_ACCON
)
&
AC_W_FINISH
)
&&
timeout
--
)
&&
--
timeout
)
mdelay
(
1
);
if
(
!
timeout
)
...
...
@@ -345,11 +345,10 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev)
goto
out
;
}
nuc900_audio
->
irq_num
=
platform_get_irq
(
pdev
,
0
);
if
(
!
nuc900_audio
->
irq_num
)
{
ret
=
-
EBUSY
;
ret
=
platform_get_irq
(
pdev
,
0
);
if
(
ret
<
0
)
goto
out
;
}
nuc900_audio
->
irq_num
=
ret
;
nuc900_ac97_data
=
nuc900_audio
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment