Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
4fcbbb67
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看板
提交
4fcbbb67
编写于
5月 23, 2009
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ASoC: Update WM8974 to use standard I2C device probe methods
Signed-off-by:
N
Mark Brown
<
broonie@opensource.wolfsonmicro.com
>
上级
1a55b3f6
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
116 addition
and
156 deletion
+116
-156
sound/soc/codecs/wm8974.c
sound/soc/codecs/wm8974.c
+116
-151
sound/soc/codecs/wm8974.h
sound/soc/codecs/wm8974.h
+0
-5
未找到文件。
sound/soc/codecs/wm8974.c
浏览文件 @
4fcbbb67
...
...
@@ -3,7 +3,7 @@
*
* Copyright 2006 Wolfson Microelectronics PLC.
*
* Author: Liam Girdwood <li
am.girdwood
@wolfsonmicro.com>
* Author: Liam Girdwood <li
nux
@wolfsonmicro.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
...
...
@@ -28,13 +28,6 @@
#include "wm8974.h"
struct
snd_soc_codec_device
soc_codec_dev_wm8974
;
/*
* wm8974 register cache
* We can't read the WM8974 register space when we are
* using 2 wire for device control, so we cache them instead.
*/
static
const
u16
wm8974_reg
[
WM8974_CACHEREGNUM
]
=
{
0x0000
,
0x0000
,
0x0000
,
0x0000
,
0x0050
,
0x0000
,
0x0140
,
0x0000
,
...
...
@@ -53,6 +46,13 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
0x0000
,
};
struct
wm8974_priv
{
struct
snd_soc_codec
codec
;
u16
reg_cache
[
WM8974_CACHEREGNUM
];
};
static
struct
snd_soc_codec
*
wm8974_codec
;
/*
* read wm8974 register cache
*/
...
...
@@ -623,217 +623,182 @@ static int wm8974_resume(struct platform_device *pdev)
return
0
;
}
/*
* initialise the WM8974 driver
* register the mixer and dsp interfaces with the kernel
*/
static
int
wm8974_init
(
struct
snd_soc_device
*
socdev
)
static
int
wm8974_probe
(
struct
platform_device
*
pdev
)
{
struct
snd_soc_codec
*
codec
=
socdev
->
card
->
codec
;
struct
snd_soc_device
*
socdev
=
platform_get_drvdata
(
pdev
);
struct
snd_soc_codec
*
codec
;
int
ret
=
0
;
codec
->
name
=
"WM8974"
;
codec
->
owner
=
THIS_MODULE
;
codec
->
read
=
wm8974_read_reg_cache
;
codec
->
write
=
wm8974_write
;
codec
->
set_bias_level
=
wm8974_set_bias_level
;
codec
->
dai
=
&
wm8974_dai
;
codec
->
num_dai
=
1
;
codec
->
reg_cache_size
=
ARRAY_SIZE
(
wm8974_reg
);
codec
->
reg_cache
=
kmemdup
(
wm8974_reg
,
sizeof
(
wm8974_reg
),
GFP_KERNEL
);
if
(
codec
->
reg_cache
==
NULL
)
return
-
ENOMEM
;
if
(
wm8974_codec
==
NULL
)
{
dev_err
(
&
pdev
->
dev
,
"Codec device not registered
\n
"
);
return
-
ENODEV
;
}
wm8974_reset
(
codec
);
socdev
->
card
->
codec
=
wm8974_codec
;
codec
=
wm8974_codec
;
/* register pcms */
ret
=
snd_soc_new_pcms
(
socdev
,
SNDRV_DEFAULT_IDX1
,
SNDRV_DEFAULT_STR1
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"wm8974: failed to create pcms
\n
"
);
dev_err
(
codec
->
dev
,
"failed to create pcms: %d
\n
"
,
ret
);
goto
pcm_err
;
}
/* power on device */
wm8974_set_bias_level
(
codec
,
SND_SOC_BIAS_STANDBY
);
wm8974_add_controls
(
codec
);
snd_soc_add_controls
(
codec
,
wm8974_snd_controls
,
ARRAY_SIZE
(
wm8974_snd_controls
));
wm8974_add_widgets
(
codec
);
ret
=
snd_soc_init_card
(
socdev
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"wm8974: failed to register card
\n
"
);
dev_err
(
codec
->
dev
,
"failed to register card: %d
\n
"
,
ret
);
goto
card_err
;
}
return
ret
;
card_err:
snd_soc_free_pcms
(
socdev
);
snd_soc_dapm_free
(
socdev
);
pcm_err:
kfree
(
codec
->
reg_cache
);
return
ret
;
}
static
struct
snd_soc_device
*
wm8974_socdev
;
#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
/*
* WM8974 2 wire address is 0x1a
*/
#define I2C_DRIVERID_WM8974 0xfefe
/* liam - need a proper id */
static
unsigned
short
normal_i2c
[]
=
{
0
,
I2C_CLIENT_END
};
/* power down chip */
static
int
wm8974_remove
(
struct
platform_device
*
pdev
)
{
struct
snd_soc_device
*
socdev
=
platform_get_drvdata
(
pdev
);
/* Magic definition of all other variables and things */
I2C_CLIENT_INSMOD
;
snd_soc_free_pcms
(
socdev
);
snd_soc_dapm_free
(
socdev
)
;
static
struct
i2c_driver
wm8974_i2c_driver
;
static
struct
i2c_client
client_template
;
return
0
;
}
/* If the i2c layer weren't so broken, we could pass this kind of data
around */
struct
snd_soc_codec_device
soc_codec_dev_wm8974
=
{
.
probe
=
wm8974_probe
,
.
remove
=
wm8974_remove
,
.
suspend
=
wm8974_suspend
,
.
resume
=
wm8974_resume
,
};
EXPORT_SYMBOL_GPL
(
soc_codec_dev_wm8974
);
static
int
wm8974_codec_probe
(
struct
i2c_adapter
*
adap
,
int
addr
,
int
kind
)
static
__devinit
int
wm8974_register
(
struct
wm8974_priv
*
wm8974
)
{
struct
snd_soc_device
*
socdev
=
wm8974_socdev
;
struct
wm8974_setup_data
*
setup
=
socdev
->
codec_data
;
struct
snd_soc_codec
*
codec
=
socdev
->
card
->
codec
;
struct
i2c_client
*
i2c
;
int
ret
;
struct
snd_soc_codec
*
codec
=
&
wm8974
->
codec
;
if
(
addr
!=
setup
->
i2c_address
)
return
-
ENODEV
;
if
(
wm8974_codec
)
{
dev_err
(
codec
->
dev
,
"Another WM8974 is registered
\n
"
);
return
-
EINVAL
;
}
client_template
.
adapter
=
adap
;
client_template
.
addr
=
addr
;
mutex_init
(
&
codec
->
mutex
);
INIT_LIST_HEAD
(
&
codec
->
dapm_widgets
);
INIT_LIST_HEAD
(
&
codec
->
dapm_paths
);
i2c
=
kmemdup
(
&
client_template
,
sizeof
(
client_template
),
GFP_KERNEL
);
if
(
i2c
==
NULL
)
{
kfree
(
codec
);
return
-
ENOMEM
;
}
i2c_set_clientdata
(
i2c
,
codec
);
codec
->
control_data
=
i2c
;
codec
->
private_data
=
wm8974
;
codec
->
name
=
"WM8974"
;
codec
->
owner
=
THIS_MODULE
;
codec
->
read
=
wm8974_read_reg_cache
;
codec
->
write
=
wm8974_write
;
codec
->
bias_level
=
SND_SOC_BIAS_OFF
;
codec
->
set_bias_level
=
wm8974_set_bias_level
;
codec
->
dai
=
&
wm8974_dai
;
codec
->
num_dai
=
1
;
codec
->
reg_cache_size
=
WM8974_CACHEREGNUM
;
codec
->
reg_cache
=
&
wm8974
->
reg_cache
;
ret
=
i2c_attach_client
(
i2c
);
memcpy
(
codec
->
reg_cache
,
wm8974_reg
,
sizeof
(
wm8974_reg
));
ret
=
wm8974_reset
(
codec
);
if
(
ret
<
0
)
{
pr_err
(
"failed to attach codec at addr %x
\n
"
,
addr
);
goto
err
;
dev_err
(
codec
->
dev
,
"Failed to issue reset
\n
"
);
return
ret
;
}
ret
=
wm8974_init
(
socdev
);
if
(
ret
<
0
)
{
pr_err
(
"failed to initialise WM8974
\n
"
);
goto
err
;
wm8974_dai
.
dev
=
codec
->
dev
;
wm8974_set_bias_level
(
codec
,
SND_SOC_BIAS_STANDBY
);
wm8974_codec
=
codec
;
ret
=
snd_soc_register_codec
(
codec
);
if
(
ret
!=
0
)
{
dev_err
(
codec
->
dev
,
"Failed to register codec: %d
\n
"
,
ret
);
return
ret
;
}
return
ret
;
err:
kfree
(
codec
);
kfree
(
i2c
);
return
ret
;
}
ret
=
snd_soc_register_dai
(
&
wm8974_dai
);
if
(
ret
!=
0
)
{
dev_err
(
codec
->
dev
,
"Failed to register DAI: %d
\n
"
,
ret
);
snd_soc_unregister_codec
(
codec
);
return
ret
;
}
static
int
wm8974_i2c_detach
(
struct
i2c_client
*
client
)
{
struct
snd_soc_codec
*
codec
=
i2c_get_clientdata
(
client
);
i2c_detach_client
(
client
);
kfree
(
codec
->
reg_cache
);
kfree
(
client
);
return
0
;
}
static
int
wm8974_i2c_attach
(
struct
i2c_adapter
*
adap
)
static
__devexit
void
wm8974_unregister
(
struct
wm8974_priv
*
wm8974
)
{
return
i2c_probe
(
adap
,
&
addr_data
,
wm8974_codec_probe
);
wm8974_set_bias_level
(
&
wm8974
->
codec
,
SND_SOC_BIAS_OFF
);
snd_soc_unregister_dai
(
&
wm8974_dai
);
snd_soc_unregister_codec
(
&
wm8974
->
codec
);
kfree
(
wm8974
);
wm8974_codec
=
NULL
;
}
/* corgi i2c codec control layer */
static
struct
i2c_driver
wm8974_i2c_driver
=
{
.
driver
=
{
.
name
=
"WM8974 I2C Codec"
,
.
owner
=
THIS_MODULE
,
},
.
id
=
I2C_DRIVERID_WM8974
,
.
attach_adapter
=
wm8974_i2c_attach
,
.
detach_client
=
wm8974_i2c_detach
,
.
command
=
NULL
,
};
static
struct
i2c_client
client_template
=
{
.
name
=
"WM8974"
,
.
driver
=
&
wm8974_i2c_driver
,
};
#endif
static
int
wm8974_probe
(
struct
platform_device
*
pdev
)
static
__devinit
int
wm8974_i2c_probe
(
struct
i2c_client
*
i2c
,
const
struct
i2c_device_id
*
id
)
{
struct
snd_soc_device
*
socdev
=
platform_get_drvdata
(
pdev
);
struct
wm8974_setup_data
*
setup
;
struct
wm8974_priv
*
wm8974
;
struct
snd_soc_codec
*
codec
;
int
ret
=
0
;
setup
=
socdev
->
codec_data
;
codec
=
kzalloc
(
sizeof
(
struct
snd_soc_codec
),
GFP_KERNEL
);
if
(
codec
==
NULL
)
wm8974
=
kzalloc
(
sizeof
(
struct
wm8974_priv
),
GFP_KERNEL
);
if
(
wm8974
==
NULL
)
return
-
ENOMEM
;
socdev
->
card
->
codec
=
codec
;
mutex_init
(
&
codec
->
mutex
);
INIT_LIST_HEAD
(
&
codec
->
dapm_widgets
);
INIT_LIST_HEAD
(
&
codec
->
dapm_paths
);
codec
=
&
wm8974
->
codec
;
codec
->
hw_write
=
(
hw_write_t
)
i2c_master_send
;
wm8974_socdev
=
socdev
;
#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
if
(
setup
->
i2c_address
)
{
normal_i2c
[
0
]
=
setup
->
i2c_address
;
codec
->
hw_write
=
(
hw_write_t
)
i2c_master_send
;
ret
=
i2c_add_driver
(
&
wm8974_i2c_driver
);
if
(
ret
!=
0
)
printk
(
KERN_ERR
"can't add i2c driver"
);
}
#else
/* Add other interfaces here */
#endif
return
ret
;
}
/* power down chip */
static
int
wm8974_remove
(
struct
platform_device
*
pdev
)
{
struct
snd_soc_device
*
socdev
=
platform_get_drvdata
(
pdev
);
struct
snd_soc_codec
*
codec
=
socdev
->
card
->
codec
;
i2c_set_clientdata
(
i2c
,
wm8974
);
codec
->
control_data
=
i2c
;
if
(
codec
->
control_data
)
wm8974_set_bias_level
(
codec
,
SND_SOC_BIAS_OFF
);
codec
->
dev
=
&
i2c
->
dev
;
snd_soc_free_pcms
(
socdev
);
snd_soc_dapm_free
(
socdev
);
#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
i2c_del_driver
(
&
wm8974_i2c_driver
);
#endif
kfree
(
codec
);
return
wm8974_register
(
wm8974
);
}
static
__devexit
int
wm8974_i2c_remove
(
struct
i2c_client
*
client
)
{
struct
wm8974_priv
*
wm8974
=
i2c_get_clientdata
(
client
);
wm8974_unregister
(
wm8974
);
return
0
;
}
struct
snd_soc_codec_device
soc_codec_dev_wm8974
=
{
.
probe
=
wm8974_probe
,
.
remove
=
wm8974_remove
,
.
suspend
=
wm8974_suspend
,
.
resume
=
wm8974_resume
,
static
const
struct
i2c_device_id
wm8974_i2c_id
[]
=
{
{
"wm8974"
,
0
},
{
}
};
MODULE_DEVICE_TABLE
(
i2c
,
wm8974_i2c_id
);
static
struct
i2c_driver
wm8974_i2c_driver
=
{
.
driver
=
{
.
name
=
"WM8974 I2C Codec"
,
.
owner
=
THIS_MODULE
,
},
.
probe
=
wm8974_i2c_probe
,
.
remove
=
__devexit_p
(
wm8974_i2c_remove
),
.
id_table
=
wm8974_i2c_id
,
};
EXPORT_SYMBOL_GPL
(
soc_codec_dev_wm8974
);
static
int
__init
wm8974_modinit
(
void
)
{
return
snd_soc_register_dai
(
&
wm8974_dai
);
return
i2c_add_driver
(
&
wm8974_i2c_driver
);
}
module_init
(
wm8974_modinit
);
static
void
__exit
wm8974_exit
(
void
)
{
snd_soc_unregister_dai
(
&
wm8974_dai
);
i2c_del_driver
(
&
wm8974_i2c_driver
);
}
module_exit
(
wm8974_exit
);
...
...
sound/soc/codecs/wm8974.h
浏览文件 @
4fcbbb67
...
...
@@ -93,11 +93,6 @@
#define WM8974_MCLKDIV_8 (6 << 5)
#define WM8974_MCLKDIV_12 (7 << 5)
struct
wm8974_setup_data
{
unsigned
short
i2c_address
;
};
extern
struct
snd_soc_dai
wm8974_dai
;
extern
struct
snd_soc_codec_device
soc_codec_dev_wm8974
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录