Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
14345a58
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
14345a58
编写于
6月 17, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'asoc/topic/sgtl5000' into asoc-next
上级
1ee9271d
b9840124
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
220 addition
and
84 deletion
+220
-84
Documentation/devicetree/bindings/sound/sgtl5000.txt
Documentation/devicetree/bindings/sound/sgtl5000.txt
+3
-0
sound/soc/codecs/sgtl5000.c
sound/soc/codecs/sgtl5000.c
+208
-59
sound/soc/codecs/sgtl5000.h
sound/soc/codecs/sgtl5000.h
+1
-1
sound/soc/fsl/imx-sgtl5000.c
sound/soc/fsl/imx-sgtl5000.c
+8
-24
未找到文件。
Documentation/devicetree/bindings/sound/sgtl5000.txt
浏览文件 @
14345a58
...
...
@@ -5,9 +5,12 @@ Required properties:
- reg : the I2C address of the device
- clocks : the clock provider of SYS_MCLK
Example:
codec: sgtl5000@0a {
compatible = "fsl,sgtl5000";
reg = <0x0a>;
clocks = <&clks 150>;
};
sound/soc/codecs/sgtl5000.c
浏览文件 @
14345a58
...
...
@@ -16,6 +16,7 @@
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/clk.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/consumer.h>
...
...
@@ -34,30 +35,30 @@
#define SGTL5000_MAX_REG_OFFSET 0x013A
/* default value of sgtl5000 registers */
static
const
u16
sgtl5000_regs
[
SGTL5000_MAX_REG_OFFSET
]
=
{
[
SGTL5000_CHIP_CLK_CTRL
]
=
0x0008
,
[
SGTL5000_CHIP_I2S_CTRL
]
=
0x0010
,
[
SGTL5000_CHIP_SSS_CTRL
]
=
0x0008
,
[
SGTL5000_CHIP_DAC_VOL
]
=
0x3c3c
,
[
SGTL5000_CHIP_PAD_STRENGTH
]
=
0x015f
,
[
SGTL5000_CHIP_ANA_HP_CTRL
]
=
0x1818
,
[
SGTL5000_CHIP_ANA_CTRL
]
=
0x0111
,
[
SGTL5000_CHIP_LINE_OUT_VOL
]
=
0x0404
,
[
SGTL5000_CHIP_ANA_POWER
]
=
0x7060
,
[
SGTL5000_CHIP_PLL_CTRL
]
=
0x5000
,
[
SGTL5000_DAP_BASS_ENHANCE
]
=
0x0040
,
[
SGTL5000_DAP_BASS_ENHANCE_CTRL
]
=
0x051f
,
[
SGTL5000_DAP_SURROUND
]
=
0x0040
,
[
SGTL5000_DAP_EQ_BASS_BAND0
]
=
0x002f
,
[
SGTL5000_DAP_EQ_BASS_BAND1
]
=
0x002f
,
[
SGTL5000_DAP_EQ_BASS_BAND2
]
=
0x002f
,
[
SGTL5000_DAP_EQ_BASS_BAND3
]
=
0x002f
,
[
SGTL5000_DAP_EQ_BASS_BAND4
]
=
0x002f
,
[
SGTL5000_DAP_MAIN_CHAN
]
=
0x8000
,
[
SGTL5000_DAP_AVC_CTRL
]
=
0x0510
,
[
SGTL5000_DAP_AVC_THRESHOLD
]
=
0x1473
,
[
SGTL5000_DAP_AVC_ATTACK
]
=
0x0028
,
[
SGTL5000_DAP_AVC_DECAY
]
=
0x0050
,
static
const
struct
reg_default
sgtl5000_reg_defaults
[]
=
{
{
SGTL5000_CHIP_CLK_CTRL
,
0x0008
}
,
{
SGTL5000_CHIP_I2S_CTRL
,
0x0010
}
,
{
SGTL5000_CHIP_SSS_CTRL
,
0x0008
}
,
{
SGTL5000_CHIP_DAC_VOL
,
0x3c3c
}
,
{
SGTL5000_CHIP_PAD_STRENGTH
,
0x015f
}
,
{
SGTL5000_CHIP_ANA_HP_CTRL
,
0x1818
}
,
{
SGTL5000_CHIP_ANA_CTRL
,
0x0111
}
,
{
SGTL5000_CHIP_LINE_OUT_VOL
,
0x0404
}
,
{
SGTL5000_CHIP_ANA_POWER
,
0x7060
}
,
{
SGTL5000_CHIP_PLL_CTRL
,
0x5000
}
,
{
SGTL5000_DAP_BASS_ENHANCE
,
0x0040
}
,
{
SGTL5000_DAP_BASS_ENHANCE_CTRL
,
0x051f
}
,
{
SGTL5000_DAP_SURROUND
,
0x0040
}
,
{
SGTL5000_DAP_EQ_BASS_BAND0
,
0x002f
}
,
{
SGTL5000_DAP_EQ_BASS_BAND1
,
0x002f
}
,
{
SGTL5000_DAP_EQ_BASS_BAND2
,
0x002f
}
,
{
SGTL5000_DAP_EQ_BASS_BAND3
,
0x002f
}
,
{
SGTL5000_DAP_EQ_BASS_BAND4
,
0x002f
}
,
{
SGTL5000_DAP_MAIN_CHAN
,
0x8000
}
,
{
SGTL5000_DAP_AVC_CTRL
,
0x0510
}
,
{
SGTL5000_DAP_AVC_THRESHOLD
,
0x1473
}
,
{
SGTL5000_DAP_AVC_ATTACK
,
0x0028
}
,
{
SGTL5000_DAP_AVC_DECAY
,
0x0050
}
,
};
/* regulator supplies for sgtl5000, VDDD is an optional external supply */
...
...
@@ -112,6 +113,8 @@ struct sgtl5000_priv {
int
fmt
;
/* i2s data format */
struct
regulator_bulk_data
supplies
[
SGTL5000_SUPPLY_NUM
];
struct
ldo_regulator
*
ldo
;
struct
regmap
*
regmap
;
struct
clk
*
mclk
;
};
/*
...
...
@@ -151,12 +154,12 @@ static int power_vag_event(struct snd_soc_dapm_widget *w,
struct
snd_kcontrol
*
kcontrol
,
int
event
)
{
switch
(
event
)
{
case
SND_SOC_DAPM_P
RE
_PMU
:
case
SND_SOC_DAPM_P
OST
_PMU
:
snd_soc_update_bits
(
w
->
codec
,
SGTL5000_CHIP_ANA_POWER
,
SGTL5000_VAG_POWERUP
,
SGTL5000_VAG_POWERUP
);
break
;
case
SND_SOC_DAPM_P
OST
_PMD
:
case
SND_SOC_DAPM_P
RE
_PMD
:
snd_soc_update_bits
(
w
->
codec
,
SGTL5000_CHIP_ANA_POWER
,
SGTL5000_VAG_POWERUP
,
0
);
msleep
(
400
);
...
...
@@ -217,12 +220,11 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
0
,
SGTL5000_CHIP_DIG_POWER
,
1
,
0
),
SND_SOC_DAPM_SUPPLY
(
"VAG_POWER"
,
SGTL5000_CHIP_ANA_POWER
,
7
,
0
,
power_vag_event
,
SND_SOC_DAPM_PRE_PMU
|
SND_SOC_DAPM_POST_PMD
),
SND_SOC_DAPM_ADC
(
"ADC"
,
"Capture"
,
SGTL5000_CHIP_ANA_POWER
,
1
,
0
),
SND_SOC_DAPM_DAC
(
"DAC"
,
"Playback"
,
SGTL5000_CHIP_ANA_POWER
,
3
,
0
),
SND_SOC_DAPM_PRE
(
"VAG_POWER_PRE"
,
power_vag_event
),
SND_SOC_DAPM_POST
(
"VAG_POWER_POST"
,
power_vag_event
),
};
/* routes for sgtl5000 */
...
...
@@ -230,16 +232,13 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = {
{
"Capture Mux"
,
"LINE_IN"
,
"LINE_IN"
},
/* line_in --> adc_mux */
{
"Capture Mux"
,
"MIC_IN"
,
"MIC_IN"
},
/* mic_in --> adc_mux */
{
"ADC"
,
NULL
,
"VAG_POWER"
},
{
"ADC"
,
NULL
,
"Capture Mux"
},
/* adc_mux --> adc */
{
"AIFOUT"
,
NULL
,
"ADC"
},
/* adc --> i2s_out */
{
"DAC"
,
NULL
,
"VAG_POWER"
},
{
"DAC"
,
NULL
,
"AIFIN"
},
/* i2s-->dac,skip audio mux */
{
"Headphone Mux"
,
"DAC"
,
"DAC"
},
/* dac --> hp_mux */
{
"LO"
,
NULL
,
"DAC"
},
/* dac --> line_out */
{
"LINE_IN"
,
NULL
,
"VAG_POWER"
},
{
"Headphone Mux"
,
"LINE_IN"
,
"LINE_IN"
},
/* line_in --> hp_mux */
{
"HP"
,
NULL
,
"Headphone Mux"
},
/* hp_mux --> hp */
...
...
@@ -909,10 +908,25 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec,
if
(
ret
)
return
ret
;
udelay
(
10
);
regcache_cache_only
(
sgtl5000
->
regmap
,
false
);
ret
=
regcache_sync
(
sgtl5000
->
regmap
);
if
(
ret
!=
0
)
{
dev_err
(
codec
->
dev
,
"Failed to restore cache: %d
\n
"
,
ret
);
regcache_cache_only
(
sgtl5000
->
regmap
,
true
);
regulator_bulk_disable
(
ARRAY_SIZE
(
sgtl5000
->
supplies
),
sgtl5000
->
supplies
);
return
ret
;
}
}
break
;
case
SND_SOC_BIAS_OFF
:
regcache_cache_only
(
sgtl5000
->
regmap
,
true
);
regulator_bulk_disable
(
ARRAY_SIZE
(
sgtl5000
->
supplies
),
sgtl5000
->
supplies
);
break
;
...
...
@@ -958,17 +972,76 @@ static struct snd_soc_dai_driver sgtl5000_dai = {
.
symmetric_rates
=
1
,
};
static
int
sgtl5000_volatile_register
(
struct
snd_soc_codec
*
codec
,
unsigned
int
reg
)
static
bool
sgtl5000_volatile
(
struct
device
*
dev
,
unsigned
int
reg
)
{
switch
(
reg
)
{
case
SGTL5000_CHIP_ID
:
case
SGTL5000_CHIP_ADCDAC_CTRL
:
case
SGTL5000_CHIP_ANA_STATUS
:
return
1
;
return
true
;
}
return
0
;
return
false
;
}
static
bool
sgtl5000_readable
(
struct
device
*
dev
,
unsigned
int
reg
)
{
switch
(
reg
)
{
case
SGTL5000_CHIP_ID
:
case
SGTL5000_CHIP_DIG_POWER
:
case
SGTL5000_CHIP_CLK_CTRL
:
case
SGTL5000_CHIP_I2S_CTRL
:
case
SGTL5000_CHIP_SSS_CTRL
:
case
SGTL5000_CHIP_ADCDAC_CTRL
:
case
SGTL5000_CHIP_DAC_VOL
:
case
SGTL5000_CHIP_PAD_STRENGTH
:
case
SGTL5000_CHIP_ANA_ADC_CTRL
:
case
SGTL5000_CHIP_ANA_HP_CTRL
:
case
SGTL5000_CHIP_ANA_CTRL
:
case
SGTL5000_CHIP_LINREG_CTRL
:
case
SGTL5000_CHIP_REF_CTRL
:
case
SGTL5000_CHIP_MIC_CTRL
:
case
SGTL5000_CHIP_LINE_OUT_CTRL
:
case
SGTL5000_CHIP_LINE_OUT_VOL
:
case
SGTL5000_CHIP_ANA_POWER
:
case
SGTL5000_CHIP_PLL_CTRL
:
case
SGTL5000_CHIP_CLK_TOP_CTRL
:
case
SGTL5000_CHIP_ANA_STATUS
:
case
SGTL5000_CHIP_SHORT_CTRL
:
case
SGTL5000_CHIP_ANA_TEST2
:
case
SGTL5000_DAP_CTRL
:
case
SGTL5000_DAP_PEQ
:
case
SGTL5000_DAP_BASS_ENHANCE
:
case
SGTL5000_DAP_BASS_ENHANCE_CTRL
:
case
SGTL5000_DAP_AUDIO_EQ
:
case
SGTL5000_DAP_SURROUND
:
case
SGTL5000_DAP_FLT_COEF_ACCESS
:
case
SGTL5000_DAP_COEF_WR_B0_MSB
:
case
SGTL5000_DAP_COEF_WR_B0_LSB
:
case
SGTL5000_DAP_EQ_BASS_BAND0
:
case
SGTL5000_DAP_EQ_BASS_BAND1
:
case
SGTL5000_DAP_EQ_BASS_BAND2
:
case
SGTL5000_DAP_EQ_BASS_BAND3
:
case
SGTL5000_DAP_EQ_BASS_BAND4
:
case
SGTL5000_DAP_MAIN_CHAN
:
case
SGTL5000_DAP_MIX_CHAN
:
case
SGTL5000_DAP_AVC_CTRL
:
case
SGTL5000_DAP_AVC_THRESHOLD
:
case
SGTL5000_DAP_AVC_ATTACK
:
case
SGTL5000_DAP_AVC_DECAY
:
case
SGTL5000_DAP_COEF_WR_B1_MSB
:
case
SGTL5000_DAP_COEF_WR_B1_LSB
:
case
SGTL5000_DAP_COEF_WR_B2_MSB
:
case
SGTL5000_DAP_COEF_WR_B2_LSB
:
case
SGTL5000_DAP_COEF_WR_A1_MSB
:
case
SGTL5000_DAP_COEF_WR_A1_LSB
:
case
SGTL5000_DAP_COEF_WR_A2_MSB
:
case
SGTL5000_DAP_COEF_WR_A2_LSB
:
return
true
;
default:
return
false
;
}
}
#ifdef CONFIG_SUSPEND
...
...
@@ -1214,7 +1287,7 @@ static int sgtl5000_replace_vddd_with_ldo(struct snd_soc_codec *codec)
static
int
sgtl5000_enable_regulators
(
struct
snd_soc_codec
*
codec
)
{
u16
reg
;
int
reg
;
int
ret
;
int
rev
;
int
i
;
...
...
@@ -1242,23 +1315,17 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
/* wait for all power rails bring up */
udelay
(
10
);
/* read chip information */
reg
=
snd_soc_read
(
codec
,
SGTL5000_CHIP_ID
);
if
(((
reg
&
SGTL5000_PARTID_MASK
)
>>
SGTL5000_PARTID_SHIFT
)
!=
SGTL5000_PARTID_PART_ID
)
{
dev_err
(
codec
->
dev
,
"Device with ID register %x is not a sgtl5000
\n
"
,
reg
);
ret
=
-
ENODEV
;
goto
err_regulator_disable
;
}
rev
=
(
reg
&
SGTL5000_REVID_MASK
)
>>
SGTL5000_REVID_SHIFT
;
dev_info
(
codec
->
dev
,
"sgtl5000 revision 0x%x
\n
"
,
rev
);
/*
* workaround for revision 0x11 and later,
* roll back to use internal LDO
*/
ret
=
regmap_read
(
sgtl5000
->
regmap
,
SGTL5000_CHIP_ID
,
&
reg
);
if
(
ret
)
goto
err_regulator_disable
;
rev
=
(
reg
&
SGTL5000_REVID_MASK
)
>>
SGTL5000_REVID_SHIFT
;
if
(
external_vddd
&&
rev
>=
0x11
)
{
/* disable all regulator first */
regulator_bulk_disable
(
ARRAY_SIZE
(
sgtl5000
->
supplies
),
...
...
@@ -1300,7 +1367,8 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
struct
sgtl5000_priv
*
sgtl5000
=
snd_soc_codec_get_drvdata
(
codec
);
/* setup i2c data ops */
ret
=
snd_soc_codec_set_cache_io
(
codec
,
16
,
16
,
SND_SOC_I2C
);
codec
->
control_data
=
sgtl5000
->
regmap
;
ret
=
snd_soc_codec_set_cache_io
(
codec
,
16
,
16
,
SND_SOC_REGMAP
);
if
(
ret
<
0
)
{
dev_err
(
codec
->
dev
,
"Failed to set cache I/O: %d
\n
"
,
ret
);
return
ret
;
...
...
@@ -1391,11 +1459,6 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
.
suspend
=
sgtl5000_suspend
,
.
resume
=
sgtl5000_resume
,
.
set_bias_level
=
sgtl5000_set_bias_level
,
.
reg_cache_size
=
ARRAY_SIZE
(
sgtl5000_regs
),
.
reg_word_size
=
sizeof
(
u16
),
.
reg_cache_step
=
2
,
.
reg_cache_default
=
sgtl5000_regs
,
.
volatile_register
=
sgtl5000_volatile_register
,
.
controls
=
sgtl5000_snd_controls
,
.
num_controls
=
ARRAY_SIZE
(
sgtl5000_snd_controls
),
.
dapm_widgets
=
sgtl5000_dapm_widgets
,
...
...
@@ -1404,28 +1467,114 @@ static struct snd_soc_codec_driver sgtl5000_driver = {
.
num_dapm_routes
=
ARRAY_SIZE
(
sgtl5000_dapm_routes
),
};
static
const
struct
regmap_config
sgtl5000_regmap
=
{
.
reg_bits
=
16
,
.
val_bits
=
16
,
.
max_register
=
SGTL5000_MAX_REG_OFFSET
,
.
volatile_reg
=
sgtl5000_volatile
,
.
readable_reg
=
sgtl5000_readable
,
.
cache_type
=
REGCACHE_RBTREE
,
.
reg_defaults
=
sgtl5000_reg_defaults
,
.
num_reg_defaults
=
ARRAY_SIZE
(
sgtl5000_reg_defaults
),
};
/*
* Write all the default values from sgtl5000_reg_defaults[] array into the
* sgtl5000 registers, to make sure we always start with the sane registers
* values as stated in the datasheet.
*
* Since sgtl5000 does not have a reset line, nor a reset command in software,
* we follow this approach to guarantee we always start from the default values
* and avoid problems like, not being able to probe after an audio playback
* followed by a system reset or a 'reboot' command in Linux
*/
static
int
sgtl5000_fill_defaults
(
struct
sgtl5000_priv
*
sgtl5000
)
{
int
i
,
ret
,
val
,
index
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
sgtl5000_reg_defaults
);
i
++
)
{
val
=
sgtl5000_reg_defaults
[
i
].
def
;
index
=
sgtl5000_reg_defaults
[
i
].
reg
;
ret
=
regmap_write
(
sgtl5000
->
regmap
,
index
,
val
);
if
(
ret
)
return
ret
;
}
return
0
;
}
static
int
sgtl5000_i2c_probe
(
struct
i2c_client
*
client
,
const
struct
i2c_device_id
*
id
)
{
struct
sgtl5000_priv
*
sgtl5000
;
int
ret
;
int
ret
,
reg
,
rev
;
sgtl5000
=
devm_kzalloc
(
&
client
->
dev
,
sizeof
(
struct
sgtl5000_priv
),
GFP_KERNEL
);
if
(
!
sgtl5000
)
return
-
ENOMEM
;
sgtl5000
->
regmap
=
devm_regmap_init_i2c
(
client
,
&
sgtl5000_regmap
);
if
(
IS_ERR
(
sgtl5000
->
regmap
))
{
ret
=
PTR_ERR
(
sgtl5000
->
regmap
);
dev_err
(
&
client
->
dev
,
"Failed to allocate regmap: %d
\n
"
,
ret
);
return
ret
;
}
sgtl5000
->
mclk
=
devm_clk_get
(
&
client
->
dev
,
NULL
);
if
(
IS_ERR
(
sgtl5000
->
mclk
))
{
ret
=
PTR_ERR
(
sgtl5000
->
mclk
);
dev_err
(
&
client
->
dev
,
"Failed to get mclock: %d
\n
"
,
ret
);
return
ret
;
}
ret
=
clk_prepare_enable
(
sgtl5000
->
mclk
);
if
(
ret
)
return
ret
;
/* read chip information */
ret
=
regmap_read
(
sgtl5000
->
regmap
,
SGTL5000_CHIP_ID
,
&
reg
);
if
(
ret
)
goto
disable_clk
;
if
(((
reg
&
SGTL5000_PARTID_MASK
)
>>
SGTL5000_PARTID_SHIFT
)
!=
SGTL5000_PARTID_PART_ID
)
{
dev_err
(
&
client
->
dev
,
"Device with ID register %x is not a sgtl5000
\n
"
,
reg
);
ret
=
-
ENODEV
;
goto
disable_clk
;
}
rev
=
(
reg
&
SGTL5000_REVID_MASK
)
>>
SGTL5000_REVID_SHIFT
;
dev_info
(
&
client
->
dev
,
"sgtl5000 revision 0x%x
\n
"
,
rev
);
i2c_set_clientdata
(
client
,
sgtl5000
);
/* Ensure sgtl5000 will start with sane register values */
ret
=
sgtl5000_fill_defaults
(
sgtl5000
);
if
(
ret
)
goto
disable_clk
;
ret
=
snd_soc_register_codec
(
&
client
->
dev
,
&
sgtl5000_driver
,
&
sgtl5000_dai
,
1
);
if
(
ret
)
goto
disable_clk
;
return
0
;
disable_clk:
clk_disable_unprepare
(
sgtl5000
->
mclk
);
return
ret
;
}
static
int
sgtl5000_i2c_remove
(
struct
i2c_client
*
client
)
{
s
nd_soc_unregister_codec
(
&
client
->
dev
);
s
truct
sgtl5000_priv
*
sgtl5000
=
i2c_get_clientdata
(
client
);
snd_soc_unregister_codec
(
&
client
->
dev
);
clk_disable_unprepare
(
sgtl5000
->
mclk
);
return
0
;
}
...
...
sound/soc/codecs/sgtl5000.h
浏览文件 @
14345a58
...
...
@@ -12,7 +12,7 @@
#define _SGTL5000_H
/*
* Register
values.
* Register
s addresses
*/
#define SGTL5000_CHIP_ID 0x0000
#define SGTL5000_CHIP_DIG_POWER 0x0002
...
...
sound/soc/fsl/imx-sgtl5000.c
浏览文件 @
14345a58
...
...
@@ -128,21 +128,11 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
goto
fail
;
}
data
->
codec_clk
=
clk_get
(
&
codec_dev
->
dev
,
NULL
);
if
(
IS_ERR
(
data
->
codec_clk
))
{
/* assuming clock enabled by default */
data
->
codec_clk
=
NULL
;
ret
=
of_property_read_u32
(
codec_np
,
"clock-frequency"
,
&
data
->
clk_frequency
);
if
(
ret
)
{
dev_err
(
&
codec_dev
->
dev
,
"clock-frequency missing or invalid
\n
"
);
goto
fail
;
}
}
else
{
data
->
clk_frequency
=
clk_get_rate
(
data
->
codec_clk
);
clk_prepare_enable
(
data
->
codec_clk
);
}
data
->
codec_clk
=
devm_clk_get
(
&
codec_dev
->
dev
,
NULL
);
if
(
IS_ERR
(
data
->
codec_clk
))
goto
fail
;
data
->
clk_frequency
=
clk_get_rate
(
data
->
codec_clk
);
data
->
dai
.
name
=
"HiFi"
;
data
->
dai
.
stream_name
=
"HiFi"
;
...
...
@@ -157,10 +147,10 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
data
->
card
.
dev
=
&
pdev
->
dev
;
ret
=
snd_soc_of_parse_card_name
(
&
data
->
card
,
"model"
);
if
(
ret
)
goto
clk_
fail
;
goto
fail
;
ret
=
snd_soc_of_parse_audio_routing
(
&
data
->
card
,
"audio-routing"
);
if
(
ret
)
goto
clk_
fail
;
goto
fail
;
data
->
card
.
num_links
=
1
;
data
->
card
.
owner
=
THIS_MODULE
;
data
->
card
.
dai_link
=
&
data
->
dai
;
...
...
@@ -170,7 +160,7 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
ret
=
snd_soc_register_card
(
&
data
->
card
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"snd_soc_register_card failed (%d)
\n
"
,
ret
);
goto
clk_
fail
;
goto
fail
;
}
platform_set_drvdata
(
pdev
,
data
);
...
...
@@ -179,8 +169,6 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
return
0
;
clk_fail:
clk_put
(
data
->
codec_clk
);
fail:
if
(
ssi_np
)
of_node_put
(
ssi_np
);
...
...
@@ -194,10 +182,6 @@ static int imx_sgtl5000_remove(struct platform_device *pdev)
{
struct
imx_sgtl5000_data
*
data
=
platform_get_drvdata
(
pdev
);
if
(
data
->
codec_clk
)
{
clk_disable_unprepare
(
data
->
codec_clk
);
clk_put
(
data
->
codec_clk
);
}
snd_soc_unregister_card
(
&
data
->
card
);
return
0
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录